<?php
namespace control;

/*
我的桌面
*/

use JetBrains\PhpStorm\ArrayShape;

class homepageClass extends adIndexClass
{
	/*返回网页*/
	public function home(): string
	{
		$menuType = $this->get('menuType') ?: '';//菜单类型
		$html     = match ($menuType) {
			'人力资源' => $this->personnelHomePage(),
			'行政管理' => $this->administrationHomePage(),
			'客户管理' => $this->clientHomePage(),
			'供应链'   => $this->erpHomePage(),
			'生产制造' => $this->produceHomePage(),
			'财务会计' => $this->accountingHomePage(),
			default    => '',
		};
		$html     = $html ?: $this->defaultHomePage();
		$style    = '<style>#body{background-color:#f2f2f2;padding:0 10px}</style>';
		return head('ad') . $style . $this->adheader([lang('public.index')]) . $html . warn() . $this->adfooter();
	}
	
	/**
	 * 判断是否需要刷新主页
	 */
	public function isRefresh(): bool|string
	{
		$menuType = $this->post('menuType') ?: '';//菜单类型
		$preMenu  = $this->post('preMenu') ?: ''; //当前主页
		$preHtml  = match ($preMenu) {
			'人力资源' => $this->personnelHomePage(),
			'行政管理' => $this->administrationHomePage(),
			'客户管理' => $this->clientHomePage(),
			'供应链'   => $this->erpHomePage(),
			'生产制造' => $this->produceHomePage(),
			'财务会计' => $this->accountingHomePage(),
			default    => '',
		};
		$html     = match ($menuType) {
			'人力资源' => $this->personnelHomePage(),
			'行政管理' => $this->administrationHomePage(),
			'客户管理' => $this->clientHomePage(),
			'供应链'   => $this->erpHomePage(),
			'生产制造' => $this->produceHomePage(),
			'财务会计' => $this->accountingHomePage(),
			default    => '',
		};
		if ($menuType == $preMenu) {
			$code = 0;
		} else {
			$code = $preHtml || $html ? 1 : 0;
		}
		
		return json_encode($code, 320);
	}
	
	/**
	 * 财务会计主页
	 */
	private function accountingHomePage(): string
	{
		// 搜索文本框
		$searchTxt =
			self::searchText([
				'click'   => "cardSearch(this)",
				'search'  => true,
				"name"    => "month",
				"title"   => "时间段",
				"class"   => "line28 width150",
				"value"   => date("Y-m") . ' ~ ' . date("Y-m"),
				'laydate' => ['range' => '~', 'type' => 'month'],
			]);
		$subject   =
			selectMultiple(["name" => "subjectId", "table" => "subject", 'where' => " coid = '" . self::$coid . "' and code in ('5601','5602','5603')", 'class' => " right line28 width150 m-r-10", 'sqlId' => 'id', 'sqlField' => 'name', 'title' => '费用科目']);
		return <<<eof
<style>
.quarter {
    width: 16%;
}
.fs-label {
    height: 16px;
    padding: 4px;
    line-height: 16px;
    color: #757575;
}
.m-r-10{
    margin-right: 10px;
}
</style>
<script src='{$this->root}static/javascript/echarts.min.js'></script>
<div class="home-warp">
    <div class="left-box">
        <div class="chart-widget">
            <p class="chart-title">业务流程图</p>
            <div id="container" class="canvas"></div>
        </div>
    </div>
    <div class="right-box">
        <div class="data-widget">
            {$this->backlog()}
        </div>
        <div style="overflow: hidden">
            <div class="data-widget">
                {$this->message()}
            </div>
        </div>
    </div>
    <div class="data-widget left m-t-0" style="width: 96.6%;">
        <form name="boardFinanceForm" data-fun="boardFinance" data-cla="homepage"><span class="title-card">数据看板</span>{$searchTxt}</form>
        <ul class="revenue" id="boardFinanceHtml">
            <li class="quarter left vertical-line">
                <div class="title-card-li-content">
                   <div>利润总额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                <div class="title-card-li-content">
                   <div>现金金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                 <div class="title-card-li-content">
                   <div>银行卡余额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
             <div class="title-card-li-content">
                   <div>存货</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
             <div class="title-card-li-content">
                   <div>应收账款</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
             <div class="title-card-li-content">
                   <div>应付账款</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
        </ul>
    </div>
    <div class="data-widget left" style="width: 96.6%;">
        <form name="profitReceivableTrendForm" data-fun="profitReceivableTrend" data-cla="homepage"><span class="title-card">应收与利润趋势</span>{$searchTxt}</form>
        <div class="data-box-show" id="profitReceivableTrendHtml"></div>
    </div>
    <div class="half left data-widget">
        <form name="expenseItemsForm" data-fun="expenseItems" data-cla="homepage"><span class="title-card">费用项目分布</span>{$searchTxt}{$subject}</form>
        <div class="data-box-show" id="expenseItemsHtml"></div>
    </div>
    <div class="half left data-widget">
        <form name="departmentalChargeForm" data-fun="departmentalCharge" data-cla="homepage"><span class="title-card">部门费用分布</span>{$searchTxt}</form>
        <div class="data-box-show" id="departmentalChargeHtml"></div>
    </div>
</div>
{$this->flowChart('container', 'accountingData')}
<script src='{$this->root}static/javascript/echarts.min.js'></script>
<script>
function search_line(form,cla,fun) {
     $("#" + fun + "Html").html("数据查询中，请稍后。。。");
     //串联表单
        var formName = form.split(",");
        var serialize = "";
        var a = "";
        for (var i = 0; i < formName.length; i++) {
            if (serialize == "") {
                a = "";
            } else {
                a = "&";
            }
            if (formName[i] != "") {
                serialize += a + $("[name=" + formName[i] + "]").serialize();
            }
        }
    $.post(root + "control/adIndex.html?cla=" + cla + "&fun=" + fun, serialize, function (data) {
         $("#" + fun + "Html").html(data.html);
    }, "json");
}

/**
* 看板搜索
*/
function cardSearch(obj){
    let searchform = $(obj).parents("form");
    let formName = searchform.attr('name');
    let fun = searchform.data('fun');
    let cla = searchform.data('cla');
    search_line(formName,cla, fun)
}

$(function() {
    search_line('boardFinanceForm','homepage', 'boardFinance')
    search_line('profitReceivableTrendForm','homepage','profitReceivableTrend');
    search_line('expenseItemsForm','homepage','expenseItems')
    search_line('departmentalChargeForm','homepage','departmentalCharge')
})
</script>
eof;
	}
	
	/**
	 * 桌面数据看板
	 */
	public function boardFinance(): bool|string
	{
		$month = $this->post('month');
		if (!empty($month)) {
			$timeArr = explode(' ~ ', $month);
		} else {
			$timeArr[0] = date('Y-m');
			$timeArr[1] = date('Y-m');
		}
		$accountRule  = companyClass::returnRule(1);
		$result       = $this->totalProfit('利润总额', $month, $accountRule);
		$profit       = $result['monthBalance'];
		$json['html'] = '';
		//利润总额
		$text         = $profit > 10000 ? '万' : '';
		$money        = round($profit > 10000 ? ($profit / 10000) : $profit, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                               <div>利润总额</div>
                                <div><span class="title-card-li-money">￥{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//现金金额
		$cash         = $this->bookkeepingBalance($month, '现金');
		$text         = $cash > 10000 ? '万' : '';
		$money        = $cash > 10000 ? round(($cash / 10000), 2) : round($cash, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                                <div>现金余额</div>
                                <div><span class="title-card-li-money">￥{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//银行卡余额
		$bank         = $this->bookkeepingBalance($month, '银行存款');
		$text         = $bank > 10000 ? '万' : '';
		$money        = round($bank > 10000 ? ($bank / 10000) : $bank, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                               <div>银行卡余额</div>
                                <div><span class="title-card-li-money">￥{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//存货
		$page                = find(array("table" => "subject as a join voucher_detail as b on a.id = b.subjectId join voucher as c on b.orderId =c.id  where a.coid = '" . self::$coid . "' and c.isTemplate = '否'  UNION select b.materialSkuId from subject as a join subject_assist as b on a.id = b.orderId", "field" => "b.materialSkuId", "where" => "a.coid = '" . self::$coid . "'  and b.initMoney >0"));
		$workFlow            = '存货';
		$projectBalanceClass = new projectBalanceClass();
		$jie                 = 0;
		foreach ($page['array'] as $array) {
			$targetId = $array['materialSkuId'];
			//$initResult = $projectBalanceClass->initMoney($workFlow, $targetId, $timeArr[0],$this->post('subjectId'));
			$monthResult = $projectBalanceClass->monthBalance($workFlow, $targetId, $timeArr[0], $timeArr[1], $this->post('subjectId'));
			//$balance = $projectBalanceClass->balance($workFlow, $targetId, $timeArr[1],$this->post('subjectId'));
			$jie += $monthResult['jieMoney'];
		}
		$text         = $jie > 10000 ? '万' : '';
		$money        = round($jie > 10000 ? ($jie / 10000) : $jie, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                                <div>存货</div>
                                <div><span class="title-card-li-money">{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//应收账款
		$and = "";
		if ($month) {
			$and .= self::timeComparison($month, 'month', 'targetDate');
		}
		$receivable   = find(array('table' => 'record', 'single' => " coid = '" . self::$coid . "' and type = '客户' " . $and, 'field' => "ifnull(sum(balance),0) as money"))['money'] ?: 0;
		$text         = $receivable > 10000 ? '万' : '';
		$money        = round($receivable > 10000 ? ($receivable / 10000) : $receivable, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                                <div>应收账款</div>
                                <div><span class="title-card-li-money">{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//应付账款
		$payable      = find(array('table' => 'record', 'single' => " coid = '" . self::$coid . "' and type = '供应商' " . $and, 'field' => "ifnull(sum(balance),0) as money"))['money'] ?: 0;
		$text         = $payable > 10000 ? '万' : '';
		$money        = round($payable > 10000 ? ($payable / 10000) : $payable, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                                <div>应付账款</div>
                                <div><span class="title-card-li-money">{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		
		return json_encode($json, 320);
	}
	
	/*资金总账*/
	public function bookkeepingBalance($month, $type)
	{
		//like查询数组
		$like = array();
		//全等查询数组
		$equal     = array(
			'coid' => self::$coid,
			'type' => $type,
		);
		$and       = " and subjectId !=''";
		$timeWhere = $voucherWhere = '';
		$startDate = '';
		if ($month) {
			$data         = explode('~', $month);
			$startDate    = trim($data[0]);
			$timeWhere    .= self::timeComparison($month, 'month', field: 'recordDate');
			$voucherWhere .= self::timeComparison($month, 'month', field: 'a.recordDate');
		}
		//获取查询结果
		$where   = search(array("like" => $like, "=" => $equal)) . $and;
		$page    = find(array('table' => "account", 'where' => $where . " order by time asc", 'field' => "*"));
		$balance = 0; //余额
		foreach ($page['array'] as $array) {
			$subject = query('subject', "id = '$array[subjectId]'");
			if (!empty($subject['id'])) {
				$subjectJieInitMoney = find(array('table' => 'voucher as a join voucher_detail as b on a.id = b.orderId', 'single' => "b.subjectId = '$array[subjectId]' and b.direction = '借' and a.isTemplate = '否' and a.coid = '" . self::$coid . "' and date_format(a.recordDate,'%Y-%m') <'$startDate'", 'field' => "ifnull(sum(b.money),0) as money"))['money'];
				$subjectDaiInitMoney = find(array('table' => 'voucher as a join voucher_detail as b on a.id = b.orderId', 'single' => "b.subjectId = '$array[subjectId]' and b.direction = '贷' and a.isTemplate = '否' and a.coid = '" . self::$coid . "' and date_format(a.recordDate,'%Y-%m') <'$startDate'", 'field' => "ifnull(sum(b.money),0) as money"))['money'];
				$subjectInitMoney    = $subjectJieInitMoney - $subjectDaiInitMoney;
				if ($subject['direction'] == '借') {
					$subjectInitMoney += $subject['initMoney'];
				} else {
					$subjectInitMoney -= $subject['initMoney'];
				}
				$subjectInitMoney = self::centToYuan($subjectInitMoney);//科目期初金额
				
				$jieMoney = find(array('table' => 'voucher as a join voucher_detail as b on a.id = b.orderId', 'single' => "b.subjectId = '$array[subjectId]' and b.direction = '借' and a.isTemplate = '否' and a.coid = '" . self::$coid . "'" . $voucherWhere, 'field' => "ifnull(sum(b.money),0) as money"))['money'];
				$daiMoney = find(array('table' => 'voucher as a join voucher_detail as b on a.id = b.orderId', 'single' => "b.subjectId = '$array[subjectId]' and b.direction = '贷' and a.isTemplate = '否' and a.coid = '" . self::$coid . "'" . $voucherWhere, 'field' => "ifnull(sum(b.money),0) as money"))['money'];
				$jieMoney = self::centToYuan($jieMoney);
				$daiMoney = self::centToYuan($daiMoney);
				
				$initMoney = find(array('table' => 'bookkeeping', 'single' => "accountId = '$array[id]' and date_format(recordDate,'%Y-%m') < '$startDate'", 'field' => "ifnull(sum(income-expenses),0) as money"))['money'];
				$initMoney += $array['initMoney'];
				
				$income  = find(array('table' => 'bookkeeping', 'where' => "accountId = '$array[id]'" . $timeWhere, 'sum' => "income"));
				$out     = find(array('table' => 'bookkeeping', 'where' => "accountId = '$array[id]'" . $timeWhere, 'sum' => "expenses"));
				$balance += ($subjectInitMoney + $jieMoney - $daiMoney) - ($initMoney + $income - $out);
			}
		}
		return $balance;
	}
	
	/**
	 * @param $name
	 * @param $month 时间区间
	 * @param $accountRule
	 * @return array
	 */
	public function totalProfit($name, $month, $accountRule): array
	{
		$money = $monthMoney = 0;
		if ($name == '营业利润') {
			$result     = $this->balance('营业收入', $month);
			$all        = find(array('table' => 'profit_income', 'where' => "pid = '营业收入' and coid = '" . self::$coid . "'"));
			$money      = $result['balance'];
			$monthMoney = $result['monthBalance'];
			if ($accountRule == 'enterpriseRule') {
				foreach ($all['array'] as $array) {
					$result = $this->balance($array['name'], $month);
					if (in_array($array['name'], ['投资收益', '公允价值变动收益'])) {
						$money      += $result['balance'];
						$monthMoney += $result['monthBalance'];
					} else {
						$money      -= $result['balance'];
						$monthMoney -= $result['monthBalance'];
					}
				}
			} elseif ($accountRule == 'smallEnterpriseRule') {
				foreach ($all['array'] as $array) {
					$result = $this->balance($array['name'], $month);
					if ($array['name'] == '投资收益') {
						$money      += $result['balance'];
						$monthMoney += $result['monthBalance'];
					} else {
						$money      -= $result['balance'];
						$monthMoney -= $result['monthBalance'];
					}
				}
			}
		} elseif ($name == '利润总额') {
			$result     = $this->totalProfit('营业利润', $month, $accountRule);
			$money      = $result['balance'];
			$monthMoney = $result['monthBalance'];
			$all        = find(array('table' => 'profit_income', 'where' => "pid = '营业利润' and coid = '" . self::$coid . "'"));
			if ($accountRule == 'enterpriseRule') {
				foreach ($all['array'] as $array) {
					$result = $this->balance($array['name'], $month);
					if (in_array($array['name'], ['营业外收入'])) {
						$money      += $result['balance'];
						$monthMoney += $result['monthBalance'];
					} else {
						$money      -= $result['balance'];
						$monthMoney -= $result['monthBalance'];
					}
				}
			} elseif ($accountRule == 'smallEnterpriseRule') {
				foreach ($all['array'] as $array) {
					$result = $this->balance($array['name'], $month);
					if (in_array($array['name'], ['营业外收入', '政府补助'])) {
						$money      += $result['balance'];
						$monthMoney += $result['monthBalance'];
					} else {
						$money      -= $result['balance'];
						$monthMoney -= $result['monthBalance'];
					}
				}
			}
		} elseif ($name == '净利润') {
			$result     = $this->totalProfit('利润总额', $month, $accountRule);
			$money      = $result['balance'];
			$monthMoney = $result['monthBalance'];
			$all        = find(array('table' => 'profit_income', 'where' => "pid = '利润总额' and coid = '" . self::$coid . "'"));
			foreach ($all['array'] as $array) {
				$result     = $this->balance($array['name'], $month);
				$money      -= $result['balance'];
				$monthMoney -= $result['monthBalance'];
			}
		} elseif ($name == '其他综合收益的税后净额') {
			$money      = 0;
			$monthMoney = 0;
		} elseif ($name == '综合收益总额') {
			$result     = $this->totalProfit('净利润', $month, $accountRule);
			$money      = $result['balance'];
			$monthMoney = $result['monthBalance'];
		}
		return ['balance' => $money, 'monthBalance' => $monthMoney];
	}
	
	/**
	 * 期末余额
	 */
	public function balance($name, $month)
	{
		$all          = find(array('table' => 'profit_income_formula', 'where' => "name = '$name' and coid = '" . self::$coid . "'"));
		$monthBalance = 0;//本期金额
		$multObj      = new multiColumnAccountClass();
		foreach ($all['array'] as $array) {
			$childMonthBalance = 0;
			$columns           = [];
			$multObj->loopSubjectIds($array['subjectId'], $columns);
			foreach ($columns as $subjectId) {
				$childMonthBalance += $this->sectionMoney($subjectId, $month, $array['rule']);
			}
			$monthBalance = match ($array['symbol']) {
				'-'     => $monthBalance - $childMonthBalance,
				default => $monthBalance + $childMonthBalance
			};
		}
		return ['balance' => 0, 'monthBalance' => $monthBalance];
	}
	
	/**
	 * 本期金额
	 */
	public function sectionMoney($subjectId, $month, $rule): float|int
	{
		if (!empty($month)) {
			$timeArr = explode(' ~ ', $month);
		} else {
			$timeArr[0] = date('Y-m');
			$timeArr[1] = date('Y-m');
		}
		$where            = " and date_format(a.recordDate,'%Y-%m') >= '$timeArr[0]' and date_format(a.recordDate,'%Y-%m') <= '$timeArr[1]' and b.subjectId = '$subjectId'";
		$jieInit          = find(array("table" => "voucher as a join voucher_detail as b on a.id = b.orderId", 'field' => "ifnull(sum(b.money),0) as money", "single" => "a.isTemplate = '否' and a.coid = '" . self::$coid . "' and b.direction = '借'" . $where . voucherClass::joinWhere()));
		$daiInit          = find(array("table" => "voucher as a join voucher_detail as b on a.id = b.orderId", 'field' => "ifnull(sum(b.money),0) as money", "single" => "a.isTemplate = '否' and a.coid = '" . self::$coid . "' and b.direction = '贷'" . $where . voucherClass::joinWhere()));
		$jieInit['money'] = self::centToYuan($jieInit['money']);
		$daiInit['money'] = self::centToYuan($daiInit['money']);
		switch ($rule) {
			case '贷方发生额':
				$balance = $daiInit['money'];
				break;
			case '借方发生额':
				$balance = $jieInit['money'];
				break;
			case '期初余额':
				$subject    = query('subject', "id = '$subjectId'");
				$initResult = $this->initMoney($subject, $timeArr[0]);
				$balance    = $initResult['jieMoney'] ?: $initResult['daiMoney'];
				break;
			default://发生额
				$balance = $jieInit['money'] ?: $daiInit['money'];
				break;
		}
		return $balance;
	}
	
	/**
	 * 期初余额
	 *
	 * @param $subject
	 * @param $startDate
	 * @return array
	 */
	public function initMoney($subject, $startDate): array
	{
		//借方
		$jieInit = find(array("table" => "voucher as a join voucher_detail as b on a.id = b.orderId", 'field' => "ifnull(sum(b.money),0) as money,ifnull(sum(b.voucherNum),0) as num", "single" => "a.isTemplate = '否' and a.coid = '" . self::$coid . "' and b.subjectId = '$subject[id]' and b.direction = '借' and date_format(a.recordDate,'%Y-%m') < '$startDate'" . voucherClass::joinWhere()));
		//贷方
		$daiInit = find(array("table" => "voucher as a join voucher_detail as b on a.id = b.orderId", 'field' => "ifnull(sum(b.money),0) as money,ifnull(sum(b.voucherNum),0) as num", "single" => "a.isTemplate = '否' and a.coid = '" . self::$coid . "' and b.subjectId = '$subject[id]' and b.direction = '贷' and date_format(a.recordDate,'%Y-%m') < '$startDate'" . voucherClass::joinWhere()));
		//期初数量
		$initNum = find(array('table' => 'subject_assist', "where" => "orderId = '$subject[id]'", 'sum' => "initNum"));
		if ($subject['direction'] == '借') {
			$jieInit['money'] += $subject['initMoney'];
			$jieInit['num']   = $jieInit['num'] + $initNum;
		} else {
			$daiInit['num']   = $daiInit['num'] + $initNum;
			$daiInit['money'] += $subject['initMoney'];
		}
		$jieInit['money'] = self::centToYuan($jieInit['money']);
		$daiInit['money'] = self::centToYuan($daiInit['money']);
		if ($jieInit['money'] > $daiInit['money']) {
			$jieMoney = $jieInit['money'] - $daiInit['money'];
			$daiMoney = 0;
		} else {
			$daiMoney = abs($jieInit['money'] - $daiInit['money']);
			$jieMoney = 0;
		}
		$result = [
			'num'      => $jieInit['num'] - $daiInit['num'],
			'price'    => abs(accountDetailsClass::division($jieInit['money'] - $daiInit['money'], $jieInit['num'] - $daiInit['num'])),
			'jieMoney' => $jieMoney,
			'daiMoney' => $daiMoney,
		];
		/*if (self::$isFormat){
			$result = accountDetailsClass::formatArrayNumber($result);
		}*/
		return $result;
	}
	
	
	/**
	 * 营收与利润趋势
	 *
	 * @return bool|string
	 */
	public function profitReceivableTrend(): bool|string
	{
		$month = $this->post('month');
		if (!empty($month)) {
			$timeArr = explode(' ~ ', $month);
		} else {
			$timeArr[0] = date('Y-01');
			$timeArr[1] = date('Y-m');
		}
		//时间段数组
		$res               = [];
		$m                 = $timeArr[0];
		$profitIncomeClass = new profitIncomeClass();
		$accountRule       = companyClass::returnRule(1);
		while ($m <= $timeArr[1]) {
			$income = $profitIncomeClass->balance('营业收入', $m);
			$profit = $profitIncomeClass->totalProfit('利润总额', $month, $accountRule);
			$res[]  = [
				'month'  => $m,
				'income' => round($income['monthBalance'] / 10000, 2),
				'profit' => round($profit['monthBalance'] / 10000, 2),
			];
			$m      = date("Y-m", strtotime($m . '-01' . " +1 month"));
		}
		$data         = [
			"subtext" => '单位：万元',
			"name"    => array_column($res, 'month'),
			"series"  => [
				[
					'name' => '营业收入',
					'data' => array_column($res, 'income'),
				],
				[
					'name' => '利润总额',
					'data' => array_column($res, 'profit'),
				],
			],
		];
		$json['html'] = $this->curve($data, 'bar');
		return json_encode($json, 320);
	}
	
	/**
	 * 费用项目分布
	 *
	 * @return bool|string
	 */
	public function expenseItems(): bool|string
	{
		$month     = $this->post('month');
		$subjectId = $this->post('subjectId');
		if (!empty($month)) {
			$timeArr = explode(' ~ ', $month);
		} else {
			$timeArr[0] = date('Y-m');
			$timeArr[1] = date('Y-m');
		}
		if (empty($subjectId)) {
			$result = find(array("table" => "subject", "field" => "id,name", "where" => " coid = '" . self::$coid . "' and code in ('5601','5602','5603') "));
		} else {
			$result = find(array("table" => "subject", "field" => "id,name", "where" => " coid = '" . self::$coid . "' and pid = '$subjectId' "));
		}
		$res                      = [];
		$subjectBalanceClass      = new subjectBalanceClass();
		$inventoryReportFormClass = new inventoryReportFormClass();
		foreach ((array)$result['array'] as $array) {
			//本期合计
			$monthResult = $subjectBalanceClass->monthBalance($timeArr[0], $timeArr[1], $array['id']);
			$res[]       = ['name' => $array['name'], 'data' => round($monthResult['daiMoney'] / 10000, 2)];
		}
		$data         = [
			"text"    => '',
			"subtext" => '单位：万元',
			"series"  => $res,
		];
		$json['html'] = $inventoryReportFormClass->pie($data);
		return json_encode($json, 320);
	}
	
	/**
	 * 部门费用分布 - 返回数据
	 */
	public function departmentalCharge(): bool|string
	{
		$month = $this->post('month');
		if (!empty($month)) {
			$timeArr = explode(' ~ ', $month);
		} else {
			$timeArr[0] = date('Y-m');
			$timeArr[1] = date('Y-m');
		}
		$department          = find(array("table" => "department", "field" => "name,id", "where" => "1=1 order by orderNo asc"));
		$projectBalanceClass = new projectBalanceClass();
		$res                 = [];
		foreach ((array)$department['array'] as $array) {
			/*$and = " and departmentId !='' and departmentId = '" . $array['id'] . "'";
			$total = 0;
			$page = find(array("table"=>"subject as a join voucher_detail as b on a.id = b.subjectId join voucher as c on b.orderId =c.id  where a.coid = '".self::$coid."' and c.isTemplate = '否'  {$and} UNION select b.departmentId from subject as a join subject_assist as b on a.id = b.orderId","field"=>"b.departmentId","where"=>"a.coid = '".self::$coid."'  and b.initMoney !=0 {$and}"));
			$workFlow = '部门';

			foreach ($page['array'] as $array) {
				$targetId = $array['departmentId'];
				//$initResult = $projectBalanceClass->initMoney($workFlow, $targetId, $timeArr[0],$this->post('subjectId'));
				$monthResult = $projectBalanceClass->monthBalance($workFlow, $targetId, $timeArr[0], $timeArr[1],$this->post('subjectId'));
				//$balance = $projectBalanceClass->balance($workFlow, $targetId, $timeArr[1],$this->post('subjectId'));
				$total += $monthResult['daiMoney'];
			}*/
			$monthResult = $projectBalanceClass->monthBalance('部门', $array['id'], $timeArr[0], $timeArr[1], $this->post('subjectId'));
			//$balance = $projectBalanceClass->balance($workFlow, $targetId, $timeArr[1],$this->post('subjectId'));
			$total = $monthResult['daiMoney'];
			$res   = [
				'name'  => $array['name'],
				'money' => round($total / 10000, 2),
			];
		}
		$data         = [
			"subtext" => '单位：万元',
			"name"    => array_column($res, 'name'),
			"series"  => [
				[
					'name' => '实际发生',
					'data' => array_column($res, 'money'),
				],
			],
		];
		$json['html'] = $this->barCharts($data);
		return json_encode($json, 320);
	}
	
	public function accountingData(): bool|string
	{
		$json['result'] = [
			/**********凭证********/
			[
				'type'   => 'group',
				'id'     => 'voucherGroup',
				'name'   => '',
				'x'      => 90,
				'y'      => 75,
				'width'  => 150,
				'height' => 450,
			],
			$this->nodeData(['page' => 'voucherEdit', 'x' => 130, 'y' => 100, 'name' => '录凭证', 'file' => 'finance']),
			$this->nodeData(['page' => 'voucher', 'x' => 130, 'y' => 250, 'name' => '查凭证', 'file' => 'finance']),
			$this->nodeData(['page' => 'voucherStatistics', 'x' => 130, 'y' => 400, 'name' => '凭证汇总', 'file' => 'finance']),
			/**********工资********/
			[
				'type'   => 'group',
				'id'     => 'wages',
				'name'   => '',
				'x'      => 300,
				'y'      => 75,
				'width'  => 150,
				'height' => 150,
			],
			$this->nodeData(['page' => 'salary', 'x' => 340, 'y' => 100, 'name' => '工资表', 'file' => 'finance']),
			/*********固定资产*******/
			[
				'type'   => 'group',
				'id'     => 'fixedAssets',
				'name'   => '',
				'x'      => 300,
				'y'      => 375,
				'width'  => 150,
				'height' => 150,
			],
			$this->nodeData(['page' => 'assetList', 'x' => 340, 'y' => 400, 'name' => '固定资产', 'title' => '固定资产清单', 'file' => 'finance']),
			/*********明细账*******/
			[
				'type'   => 'group',
				'id'     => 'subLedger',
				'name'   => '',
				'x'      => 510,
				'y'      => 75,
				'width'  => 270,
				'height' => 450,
			],
			$this->nodeData(['page' => 'accountDetails', 'x' => 550, 'y' => 100, 'name' => '明细账', 'file' => 'finance']),
			$this->nodeData(['page' => 'projectDetails', 'x' => 670, 'y' => 100, 'name' => '项目明细账', 'title' => '核算项目明细账', 'file' => 'finance']),
			$this->nodeData(['page' => 'accountTotal', 'x' => 550, 'y' => 250, 'name' => '总账', 'file' => 'finance']),
			$this->nodeData(['page' => 'projectBalance', 'x' => 670, 'y' => 250, 'name' => '项目余额表', 'title' => '核算项目余额表', 'file' => 'finance']),
			$this->nodeData(['page' => 'subjectBalance', 'x' => 550, 'y' => 400, 'name' => '科目余额表', 'file' => 'finance']),
			$this->nodeData(['page' => 'multiColumnAccount', 'x' => 670, 'y' => 400, 'name' => '多栏账', 'file' => 'finance']),
			/*********************/
			$this->nodeData(['page' => 'carryover', 'x' => 840, 'y' => 170, 'name' => '期末结转', 'file' => 'finance']),
			$this->nodeData(['page' => 'checkout', 'x' => 840, 'y' => 330, 'name' => '结账', 'file' => 'finance']),
			/*********汇总表*******/
			[
				'type'   => 'group',
				'id'     => 'summary',
				'name'   => '',
				'x'      => 980,
				'y'      => 75,
				'width'  => 150,
				'height' => 450,
			],
			$this->nodeData(['page' => 'assetDebt', 'x' => 1020, 'y' => 100, 'name' => '资产负债表', 'file' => 'finance']),
			$this->nodeData(['page' => 'profitIncome', 'x' => 1020, 'y' => 250, 'name' => '利润表', 'file' => 'finance']),
			$this->nodeData(['page' => 'cashFlow', 'x' => 1020, 'y' => 400, 'name' => '现金流量表', 'file' => 'finance']),
			/*********流程表*******/
			[
				'type'   => 'group',
				'id'     => 'flow',
				'name'   => '',
				'x'      => 90,
				'y'      => 585,
				'width'  => 690,
				'height' => 450,
			],
			$this->nodeData(['page' => 'saleSendOrder', 'x' => 130, 'y' => 610, 'name' => '销售发货单', 'file' => 'finance']),
			$this->nodeData(['page' => 'incomeDetails', 'x' => 130, 'y' => 760, 'name' => '应收账款', 'title' => '应收账款明细表', 'file' => 'finance']),
			$this->nodeData(['page' => 'inReceipt', 'x' => 130, 'y' => 910, 'name' => '收款单', 'file' => 'finance']),
			$this->nodeData(['page' => 'writeOffOrder', 'x' => 260, 'y' => 760, 'name' => '核销单', 'file' => 'finance']),
			$this->nodeData(['page' => 'purchaseGetOrder', 'x' => 390, 'y' => 610, 'name' => '采购收货单', 'file' => 'finance']),
			$this->nodeData(['page' => 'payDetails', 'x' => 390, 'y' => 760, 'name' => '应付账款', 'title' => '应付账款明细表', 'file' => 'finance']),
			$this->nodeData(['page' => 'payReceipt', 'x' => 390, 'y' => 910, 'name' => '付款单', 'file' => 'finance']),
			$this->nodeData(['page' => 'outsourceSettle', 'x' => 520, 'y' => 610, 'name' => '委外结算单', 'file' => 'finance']),
			$this->nodeData(['page' => 'otherInReceipt', 'x' => 520, 'y' => 910, 'name' => '其他收入单', 'file' => 'finance']),
			$this->nodeData(['page' => 'transferReceipt', 'x' => 650, 'y' => 760, 'name' => '转账单', 'file' => 'finance']),
			$this->nodeData(['page' => 'otherOutReceipt', 'x' => 650, 'y' => 910, 'name' => '其他支出单', 'file' => 'finance']),
			/*********记账*******/
			[
				'type'   => 'group',
				'id'     => 'bookkeeping',
				'name'   => '',
				'x'      => 860,
				'y'      => 585,
				'width'  => 270,
				'height' => 450,
			],
			$this->nodeData(['page' => 'cashBook', 'x' => 900, 'y' => 610, 'name' => '现金日记账', 'file' => 'finance']),
			$this->nodeData(['page' => 'financialReport', 'x' => 1030, 'y' => 610, 'name' => '资金报表', 'file' => 'finance']),
			
			$this->nodeData(['page' => 'bankBook', 'x' => 900, 'y' => 760, 'name' => '银行日记账', 'file' => 'finance']),
			$this->nodeData(['page' => 'generalAccount', 'x' => 1030, 'y' => 760, 'name' => '核对总账', 'file' => 'finance']),
			
			$this->nodeData(['page' => 'innerTransfer', 'x' => 900, 'y' => 910, 'name' => '内部转账', 'file' => 'finance']),
		];
		$json['link']   = [
			//group link
			['source' => 'voucherGroup', 'target' => 'subLedger', 'vertices' => []],
			['source' => 'wages', 'target' => 'voucherGroup', 'vertices' => []],
			['source' => 'fixedAssets', 'target' => 'voucherGroup', 'vertices' => []],
			['source' => 'flow', 'target' => 'bookkeeping', 'vertices' => []],
			//node link
			['source' => 'subLedger', 'target' => 'carryover', 'vertices' => []],
			['source' => 'carryover', 'target' => 'checkout', 'vertices' => []],
			['source' => 'checkout', 'target' => 'summary', 'vertices' => []],
			['source' => 'bookkeeping', 'target' => 'checkout', 'vertices' => []],
			
			['source' => 'saleSendOrder', 'target' => 'incomeDetails', 'vertices' => []],
			['source' => 'inReceipt', 'target' => 'incomeDetails', 'vertices' => []],
			['source' => 'incomeDetails', 'target' => 'writeOffOrder', 'vertices' => []],
			['source' => 'payDetails', 'target' => 'writeOffOrder', 'vertices' => []],
			['source' => 'purchaseGetOrder', 'target' => 'payDetails', 'vertices' => []],
			['source' => 'payReceipt', 'target' => 'payDetails', 'vertices' => []],
			['source' => 'outsourceSettle', 'target' => 'payDetails', 'vertices' => [['x' => 555, 'y' => 800]]],
		];
		return json_encode($json, 320);
	}
	
	/**
	 * 供应链主页
	 */
	private function erpHomePage(): string
	{
		// 搜索文本框
		$searchTxt =
			self::searchText([
				'click'   => "cardSearch(this)",
				'search'  => true,
				"name"    => "date",
				"title"   => "时间段",
				"class"   => "line28 width200",
				"value"   => '',
				'laydate' => ['range' => '~', 'type' => 'date'],
			]);
		return <<<eof
<script src='{$this->root}static/javascript/echarts.min.js'></script>
<div class="home-warp">
    <div class="left-box">
        <div class="chart-widget">
            <p class="chart-title">业务流程图</p>
            <div id="container" class="canvas"></div>
        </div>
    </div>
    <div class="right-box">
        <div class="data-widget">
            {$this->backlog()}
        </div>
        <div style="overflow: hidden">
            <div class="data-widget">
                {$this->alertMessage()}
            </div>
        </div>
    </div>
    <div class="data-widget left m-t-0" style="width: 96.6%;">
        <form name="boardHomeForm" data-fun="boardHome" data-cla="salesReportForm"><span class="title-card">数据看板</span>{$searchTxt}</form>
        <ul class="revenue" id="boardHomeHtml">
            <li class="quarter left vertical-line">
                <div class="title-card-li-content">
                   <div>销售金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                <div class="title-card-li-content">
                   <div>回款金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                 <div class="title-card-li-content">
                   <div>材料采购金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
             <div class="title-card-li-content">
                   <div>库存金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
        </ul>
    </div>
    <div class="data-widget left" style="width: 96.6%;">
        <form name="salesStatisticsForm" data-fun="salesStatistics" data-cla="salesReportForm"><span class="title-card">销售统计</span>{$searchTxt}</form>
        <div class="data-box-show" id="salesStatisticsHtml"></div>
    </div>
    <div class="half left data-widget">
        <form name="purchaseStatisticsForm" data-fun="purchaseStatistics" data-cla="purchaseReportForm"><span class="title-card">采购统计</span>{$searchTxt}</form>
        <div class="data-box-show" id="purchaseStatisticsHtml"></div>
    </div>
    <div class="half left data-widget">
        <form name="stockAgeForm" data-fun="stockAge" data-cla="inventoryReportForm"><span class="title-card">库龄分布</span>{$searchTxt}</form>
        <div class="data-box-show" id="stockAgeHtml"></div>
    </div>
</div>
{$this->flowChart('container', 'erpData')}
<script src='{$this->root}static/javascript/echarts.min.js'></script>
<script>
function search_line(form,cla,fun) {
     $("#" + fun + "Html").html("数据查询中，请稍后。。。");
     //串联表单
        var formName = form.split(",");
        var serialize = "";
        var a = "";
        for (var i = 0; i < formName.length; i++) {
            if (serialize == "") {
                a = "";
            } else {
                a = "&";
            }
            if (formName[i] != "") {
                serialize += a + $("[name=" + formName[i] + "]").serialize();
            }
        }
    $.post(root + "control/adIndex.html?cla=" + cla + "&fun=" + fun, serialize, function (data) {
         $("#" + fun + "Html").html(data.html);
    }, "json");
}

/**
* 看板搜索
*/
function cardSearch(obj){
    let searchform = $(obj).parents("form");
    let formName = searchform.attr('name');
    let fun = searchform.data('fun');
    let cla = searchform.data('cla');
    search_line(formName,cla, fun)
}

$(function() {
    search_line('boardHomeForm','salesReportForm', 'boardHome')
    search_line('salesStatisticsForm','salesReportForm','salesStatistics');
    search_line('purchaseStatisticsForm','purchaseReportForm','purchaseStatistics')
    search_line('stockAgeForm','inventoryReportForm','stockAge')
})
</script>
eof;
	}
	
	/** 生成节点数据
	 *
	 * @param array $data
	 * @return array
	 */
	public function nodeData(array $data): array
	{
		$page = isset($data['page']) ? $data['page'] : '';
		if ($page) {
			$name = isset($data['name']) ? $data['name'] : '';
			$file = isset($data['file']) ? $data['file'] : 'client';
			return [
				'type'  => 'node',
				'id'    => $page,
				'x'     => isset($data['x']) ? $data['x'] : '',
				'y'     => isset($data['y']) ? $data['y'] : '',
				'name'  => $name,
				'title' => isset($data['title']) ? $data['title'] : $name,
				'power' => $this->power($page, 'see'),
				'img'   => root . 'img/flowChart/' . $file . '/' . ($this->power($page, 'see') ? $page : $page . '_noauth') . '.svg',
				'url'   => root . "control/adIndex.html?cla={$page}&fun=home",
			];
		} else {
			return [];
		}
	}
	
	public function erpData(): bool|string
	{
		$json['result'] = [
			/**********销售********/
			[
				'type'   => 'group',
				'id'     => 'saleGroup',
				'name'   => '',
				'x'      => 30,
				'y'      => 75,
				'width'  => 270,
				'height' => 600,
			],
			$this->nodeData(['page' => 'orderStore', 'x' => 55, 'y' => 100, 'name' => '订货订单', 'file' => 'erp']),
			$this->nodeData(['page' => 'salesContract', 'x' => 205, 'y' => 100, 'name' => '销售合同', 'file' => 'erp']),
			$this->nodeData(['page' => 'saleOrder', 'x' => 130, 'y' => 250, 'name' => '销售订单', 'file' => 'erp']),
			$this->nodeData(['page' => 'saleSendOrder', 'x' => 55, 'y' => 400, 'name' => '销售发货单', 'file' => 'erp']),
			$this->nodeData(['page' => 'saleRefundOrder', 'x' => 205, 'y' => 400, 'name' => '销售退货单', 'file' => 'erp']),
			$this->nodeData(['page' => 'saleInvoice', 'x' => 130, 'y' => 550, 'name' => '销售发票', 'file' => 'erp']),
			/**********生产制造********/
			[
				'type'   => 'group',
				'id'     => 'produceGroup',
				'name'   => '生产制造',
				'x'      => 380,
				'y'      => 75,
				'width'  => 150,
				'height' => 120,
			],
			/**********售后********/
			[
				'type'   => 'group',
				'id'     => 'afterSales',
				'name'   => '',
				'x'      => 380,
				'y'      => 240,
				'width'  => 150,
				'height' => 120,
			],
			$this->nodeData(['page' => 'aftermarketRegister', 'x' => 420, 'y' => 260, 'name' => '售后登记', 'title' => '维修登记', 'file' => 'erp']),
			/**********物流********/
			[
				'type'   => 'group',
				'id'     => 'logistics',
				'name'   => '',
				'x'      => 380,
				'y'      => 405,
				'width'  => 150,
				'height' => 270,
			],
			$this->nodeData(['page' => 'logisticsCar', 'x' => 420, 'y' => 420, 'name' => '车辆管理', 'title' => '内部车辆', 'file' => 'erp']),
			$this->nodeData(['page' => 'deliveryManage', 'x' => 420, 'y' => 550, 'name' => '发货管理', 'file' => 'erp']),
			/**********采购********/
			[
				'type'   => 'group',
				'id'     => 'purchase',
				'name'   => '',
				'x'      => 625,
				'y'      => 75,
				'width'  => 270,
				'height' => 600,
			],
			$this->nodeData(['page' => 'purchaseApply', 'x' => 660, 'y' => 100, 'name' => '采购申请', 'title' => '订货订单', 'file' => 'erp']),
			$this->nodeData(['page' => 'purchaseContract', 'x' => 810, 'y' => 100, 'name' => '采购合同', 'file' => 'erp']),
			$this->nodeData(['page' => 'purchaseOrder', 'x' => 735, 'y' => 250, 'name' => '采购订单', 'file' => 'erp']),
			$this->nodeData(['page' => 'purchaseGetOrder', 'x' => 660, 'y' => 400, 'name' => '采购收货单', 'file' => 'erp']),
			$this->nodeData(['page' => 'purchaseRefundOrder', 'x' => 810, 'y' => 400, 'name' => '采购退货单', 'file' => 'erp']),
			$this->nodeData(['page' => 'incomeInvoice', 'x' => 735, 'y' => 550, 'name' => '采购发票', 'title' => '进项发票', 'file' => 'erp']),
			/*********委外*********/
			[
				'type'   => 'group',
				'id'     => 'outsource',
				'name'   => '',
				'x'      => 990,
				'y'      => 75,
				'width'  => 270,
				'height' => 600,
			],
			$this->nodeData(['page' => 'outsourceContract', 'x' => 1015, 'y' => 100, 'name' => '委外合同', 'file' => 'erp']),
			$this->nodeData(['page' => 'outsourcePickRefund', 'x' => 1165, 'y' => 100, 'name' => '委外退料单', 'file' => 'erp']),
			$this->nodeData(['page' => 'outsourceProcess', 'x' => 1015, 'y' => 250, 'name' => '委外加工单', 'file' => 'erp']),
			$this->nodeData(['page' => 'outsourcePick', 'x' => 1165, 'y' => 250, 'name' => '委外发料单', 'file' => 'erp']),
			$this->nodeData(['page' => 'outsourceGet', 'x' => 1015, 'y' => 400, 'name' => '委外收货单', 'file' => 'erp']),
			$this->nodeData(['page' => 'outsourceRefund', 'x' => 1015, 'y' => 550, 'name' => '委外退货单', 'file' => 'erp']),
			$this->nodeData(['page' => 'outsourceSettle', 'x' => 1165, 'y' => 550, 'name' => '委外结算单', 'file' => 'erp']),
			/**********库存********/
			[
				'type'   => 'group',
				'id'     => 'inventoryGroup',
				'name'   => '',
				'x'      => 30,
				'y'      => 765,
				'width'  => 1230,
				'height' => 270,
			],
			$this->nodeData(['page' => 'inStock', 'x' => 55, 'y' => 790, 'name' => '入库', 'file' => 'erp']),
			$this->nodeData(['page' => 'outStock', 'x' => 185, 'y' => 790, 'name' => '出库', 'file' => 'erp']),
			$this->nodeData(['page' => 'moveStock', 'x' => 315, 'y' => 790, 'name' => '移库', 'file' => 'erp']),
			$this->nodeData(['page' => 'inventoryAllot', 'x' => 455, 'y' => 790, 'name' => '调拨单', 'file' => 'erp']),
			$this->nodeData(['page' => 'inventory', 'x' => 595, 'y' => 790, 'name' => '盘点单', 'file' => 'erp']),
			/*$this->nodeData(['page' => 'assembly', 'x' => 595, 'y' => 790, 'name' => '组装单', 'file' => 'erp']),
			$this->nodeData(['page' => 'dismantle', 'x' => 735, 'y' => 790, 'name' => '拆解单', 'file' => 'erp']),
			$this->nodeData(['page' => 'inStockOther', 'x' => 885, 'y' => 790, 'name' => '其他入库单', 'file' => 'erp']),
			$this->nodeData(['page' => 'outStockOther', 'x' => 1035, 'y' => 790, 'name' => '其他出库单', 'file' => 'erp']),
			$this->nodeData(['page' => 'inventory', 'x' => 1170, 'y' => 790, 'name' => '盘点单', 'file' => 'erp']),*/
			$this->nodeData(['page' => 'inventoryBalance', 'x' => 535, 'y' => 930, 'name' => '库存余额表', 'file' => 'erp']),
		];
		$json['link']   = [
			//group link
			['source' => 'saleGroup', 'target' => 'inventoryGroup', 'vertices' => []],
			['source' => 'saleGroup', 'target' => 'produceGroup', 'vertices' => []],
			['source' => 'saleGroup', 'target' => 'afterSales', 'vertices' => []],
			['source' => 'saleGroup', 'target' => 'logistics', 'vertices' => []],
			['source' => 'produceGroup', 'target' => 'purchase', 'vertices' => []],
			['source' => 'produceGroup', 'target' => 'outsource', 'vertices' => [['x' => 455, 'y' => 40], ['x' => 1140, 'y' => 40]]],
			['source' => 'logistics', 'target' => 'inventoryGroup', 'vertices' => []],
			['source' => 'purchase', 'target' => 'inventoryGroup', 'vertices' => [['x' => 760, 'y' => 675]]],
			['source' => 'outsource', 'target' => 'inventoryGroup', 'vertices' => []],
			//node link
			//销售
			['source' => 'orderStore', 'target' => 'saleOrder', 'vertices' => [['x' => 90, 'y' => 290]]],
			['source' => 'salesContract', 'target' => 'saleOrder', 'vertices' => [['x' => 240, 'y' => 290]]],
			['source' => 'saleOrder', 'target' => 'saleSendOrder', 'vertices' => [['x' => 165, 'y' => 360], ['x' => 90, 'y' => 360]]],
			['source' => 'saleSendOrder', 'target' => 'saleInvoice', 'vertices' => [['x' => 90, 'y' => 510], ['x' => 165, 'y' => 510]]],
			['source' => 'saleRefundOrder', 'target' => 'saleInvoice', 'vertices' => [['x' => 240, 'y' => 510], ['x' => 165, 'y' => 510]]],
			['source' => 'saleSendOrder', 'target' => 'saleRefundOrder', 'vertices' => []],
			//物流
			['source' => 'logisticsCar', 'target' => 'deliveryManage', 'vertices' => []],
			//采购
			['source' => 'purchaseApply', 'target' => 'purchaseOrder', 'vertices' => [['x' => 695, 'y' => 290]]],
			['source' => 'purchaseContract', 'target' => 'purchaseOrder', 'vertices' => [['x' => 845, 'y' => 290]]],
			['source' => 'purchaseOrder', 'target' => 'purchaseGetOrder', 'vertices' => [['x' => 770, 'y' => 360], ['x' => 695, 'y' => 360]]],
			['source' => 'purchaseGetOrder', 'target' => 'incomeInvoice', 'vertices' => [['x' => 695, 'y' => 510], ['x' => 770, 'y' => 510]]],
			['source' => 'purchaseRefundOrder', 'target' => 'incomeInvoice', 'vertices' => [['x' => 845, 'y' => 510], ['x' => 770, 'y' => 510]]],
			['source' => 'purchaseGetOrder', 'target' => 'purchaseRefundOrder', 'vertices' => []],
			//委外
			['source' => 'outsourceContract', 'target' => 'outsourceProcess', 'vertices' => []],
			['source' => 'outsourcePick', 'target' => 'outsourcePickRefund', 'vertices' => []],
			['source' => 'outsourceProcess', 'target' => 'outsourcePick', 'vertices' => []],
			['source' => 'outsourceProcess', 'target' => 'outsourceGet', 'vertices' => []],
			['source' => 'outsourceGet', 'target' => 'outsourceRefund', 'vertices' => []],
			['source' => 'outsourceRefund', 'target' => 'outsourceSettle', 'vertices' => []],
			['source' => 'outsourcePick', 'target' => 'outsourceSettle', 'vertices' => []],
			['source' => 'outsourceGet', 'target' => 'outsourceSettle', 'vertices' => [['x' => 1200, 'y' => 440]]],
			//库存
			['source' => 'inventoryAllot', 'target' => 'inventoryBalance', 'vertices' => [['x' => 490, 'y' => 960]]],
			['source' => 'moveStock', 'target' => 'inventoryBalance', 'vertices' => [['x' => 350, 'y' => 960]]],
			['source' => 'outStock', 'target' => 'inventoryBalance', 'vertices' => [['x' => 220, 'y' => 960]]],
			['source' => 'inStock', 'target' => 'inventoryBalance', 'vertices' => [['x' => 90, 'y' => 960]]],
			
			/*['source' => 'assembly', 'target' => 'inventoryBalance', 'vertices' => [['x' => 630, 'y' => 960]]],
			['source' => 'dismantle', 'target' => 'inventoryBalance', 'vertices' => [['x' => 770, 'y' => 960]]],
			['source' => 'inStockOther', 'target' => 'inventoryBalance', 'vertices' => [['x' => 920, 'y' => 960]]],
			['source' => 'outStockOther', 'target' => 'inventoryBalance', 'vertices' => [['x' => 1070, 'y' => 960]]],*/
		];
		return json_encode($json, 320);
	}
	
	/**
	 * 生产制造主页
	 */
	private function produceHomePage(): string
	{
		// 搜索文本框
		$searchTxt =
			self::searchText([
				'click'   => "cardSearch(this)",
				'search'  => true,
				"name"    => "date",
				"title"   => "时间段",
				"class"   => "line28 width200",
				"value"   => '',
				'laydate' => ['range' => '~', 'type' => 'date'],
			]);
		return <<<eof
<script src='{$this->root}static/javascript/echarts.min.js'></script>
<div class="home-warp">
    <div class="left-box">
        <div class="chart-widget">
            <p class="chart-title">业务流程图</p>
            <div id="container" class="canvas"></div>
        </div>
    </div>
    <div class="right-box">
        <div class="data-widget">
            {$this->backlog()}
        </div>
        <div style="overflow: hidden">
            <div class="data-widget">
                {$this->alertMessage()}
            </div>
        </div>
    </div>
    <div class="data-widget left m-t-0" style="width: 96.6%;">
        <form name="boardProduceForm" data-fun="boardProduce" data-cla="homepage"><span class="title-card">数据看板</span>{$searchTxt}</form>
        <ul class="revenue" id="boardProduceHtml">
            <li class="quarter left vertical-line">
                <div class="title-card-li-content">
                   <div>产值</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                <div class="title-card-li-content">
                   <div>材料</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                 <div class="title-card-li-content">
                   <div>人工</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
             <div class="title-card-li-content">
                   <div>分摊费用</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
        </ul>
    </div>
    <div class="data-widget left" style="width: 96.6%;">
        <form name="outputValueStatisticsForm" data-fun="outputValueStatistics" data-cla="homepage"><span class="title-card">产值统计</span>{$searchTxt}</form>
        <div class="data-box-show" id="outputValueStatisticsHtml"></div>
    </div>
    <div class="half left data-widget">
        <form name="materialConsumptionForm" data-fun="materialConsumption" data-cla="homepage"><span class="title-card">材料耗用</span>{$searchTxt}</form>
        <div class="data-box-show" id="materialConsumptionHtml"></div>
    </div>
    <div class="half left data-widget">
        <form name="wageForm" data-fun="wage" data-cla="homepage"><span class="title-card">计时计件工资</span>{$searchTxt}</form>
        <div class="data-box-show" id="wageHtml"></div>
    </div>
</div>
{$this->flowChart('container', 'produceData')}
<script src='{$this->root}static/javascript/echarts.min.js'></script>
<script>
function search_line(form,cla,fun) {
     $("#" + fun + "Html").html("数据查询中，请稍后。。。");
     //串联表单
        var formName = form.split(",");
        var serialize = "";
        var a = "";
        for (var i = 0; i < formName.length; i++) {
            if (serialize == "") {
                a = "";
            } else {
                a = "&";
            }
            if (formName[i] != "") {
                serialize += a + $("[name=" + formName[i] + "]").serialize();
            }
        }
    $.post(root + "control/adIndex.html?cla=" + cla + "&fun=" + fun, serialize, function (data) {
         $("#" + fun + "Html").html(data.html);
    }, "json");
}

/**
* 看板搜索
*/
function cardSearch(obj){
    let searchform = $(obj).parents("form");
    let formName = searchform.attr('name');
    let fun = searchform.data('fun');
    let cla = searchform.data('cla');
    search_line(formName,cla, fun)
}

$(function() {
    search_line('boardProduceForm','homepage', 'boardProduce')
    search_line('outputValueStatisticsForm','homepage','outputValueStatistics');
    search_line('materialConsumptionForm','homepage','materialConsumption')
    search_line('wageForm','homepage','wage')
})
</script>
eof;
	}
	
	/**
	 * 桌面数据看板
	 */
	public function boardProduce(): bool|string
	{
		$output_value_tip = componentClass::tipComponent('产值=产量*销售基准价（不含税）', '?');
		$material_fee_tip = componentClass::tipComponent('材料=材料耗用数量*出库成本', '?');
		$people_fee_tip   = componentClass::tipComponent('人工=计时工资+计件工资', '?');
		$date             = $this->post('date');
		$where            = " and a.coid = '" . self::$coid . "' and a.state = '已确认' ";
		if ($date) {
			$where .= self::timeComparison($date, field: 'a.recordDate');
		}
		$outputValue    = 0; //产值
		$materialFee    = 0; //材料
		$peopleFee      = 0; //人工
		$costSharing    = 0; //分摊费用
		$costCountClass = new costCountClass();
		$result         = find(array("table" => "machining_order as a join machining_order_mx as mx on a.id = mx.orderId", "field" => "a.*,mx.id as mxId,mx.materialId", "where" => " 1 " . $where . " order by a.recordDate desc,a.time desc"));
		if (is_array($result['array'])) {
			foreach ($result['array'] as $array) {
				$material    = query("material", " id = '$array[materialId]' ", "salePrice");
				$result      = $costCountClass->inFee($array['mxId']);
				$peopleFee   += $costCountClass->peopleFee($array['mxId']);
				$materialFee += $costCountClass->materialFee($array['mxId']);
				$outputValue += $result['num'] * $material['salePrice'];
				$costSharing += $result['money'];
			}
		}
		$json['html'] = '';
		//产值
		$text         = $outputValue > 10000 ? '万' : '';
		$money        = round($outputValue > 10000 ? ($outputValue / 10000) : $outputValue, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                               <div>产值{$output_value_tip}</div>
                                <div><span class="title-card-li-money">￥{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//材料
		$text         = $materialFee > 10000 ? '万' : '';
		$money        = $materialFee > 10000 ? round(($materialFee / 10000), 2) : round($materialFee, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                                <div>材料{$material_fee_tip}</div>
                                <div><span class="title-card-li-money">￥{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//人工
		$text         = $peopleFee > 10000 ? '万' : '';
		$money        = round($peopleFee > 10000 ? ($peopleFee / 10000) : $peopleFee, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                               <div>人工{$people_fee_tip}</div>
                                <div><span class="title-card-li-money">￥{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		//分摊费用
		$text         = $costSharing > 10000 ? '万' : '';
		$money        = round($costSharing > 10000 ? ($costSharing / 10000) : $costSharing, 2);
		$json['html'] .= <<<efo
                        <li class="quarter left vertical-line">
                            <div class="title-card-li-content">
                                <div>分摊费用</div>
                                <div><span class="title-card-li-money">{$money}</span><span>{$text}</span></div>
                            </div>
                        </li>
         
efo;
		
		return json_encode($json, 320);
	}
	
	/**
	 * 产值统计
	 *
	 * @return bool|string
	 */
	public function outputValueStatistics(): bool|string
	{
		$date = $this->post('date');
		if (!empty($date)) {
			$timeArr = explode(' ~ ', $date);
		} else {
			$timeArr[0] = date('Y-m-d', strtotime("-14 day"));
			$timeArr[1] = $this->date;
		}
		//时间段数组
		$dateArr = [];
		$m       = $timeArr[0];
		while ($m <= $timeArr[1]) {
			$dateArr[] = ['name' => date("m月d日", strtotime($m)), 'date' => $m];
			$m         = date("Y-m-d", strtotime($m . " +1 day"));
		}
		
		$costCountClass = new costCountClass();
		//车间
		$product_line = find(array("table" => "product_line", "field" => "workshop", "where" => " coid = '" . self::$coid . "' and state = '启用' group by workshop "));
		$series       = [];
		foreach ((array)$product_line['array'] as $array) {
			$res = [];
			foreach ((array)$dateArr as $val) {
				$where       = " and a.coid = '" . self::$coid . "' and a.state = '已确认' and a.recordDate = '$val[date]' and a.lineId in (select id from product_line where workshop = '$array[workshop]') ";
				$outputValue = 0; //产值
				$result      = find(array("table" => "machining_order as a join machining_order_mx as mx on a.id = mx.orderId", "field" => "a.*,mx.id as mxId,mx.materialId", "where" => " 1 " . $where . " order by a.recordDate desc,a.time desc"));
				
				if (is_array($result['array'])) {
					foreach ($result['array'] as $arr) {
						$material    = query("material", " id = '$arr[materialId]' ", "salePrice");
						$result      = $costCountClass->inFee($arr['mxId']);
						$outputValue += $result['num'] * $material['salePrice'];
					}
				}
				$res[] = round($outputValue / 10000, 2);
			}
			//每个车间产值
			$series[] = [
				'name'     => $array['workshop'],
				'stack'    => 'value',
				'emphasis' => json_encode(['focus' => 'series']),
				'data'     => $res,
			];
		}
		$data         = [
			"subtext" => '单位：万元',
			"name"    => array_column($dateArr, 'name'),
			"series"  => $series,
		];
		$json['html'] = $this->curve($data, 'bar');
		return json_encode($json, 320);
	}
	
	/**
	 * 材料耗用
	 *
	 * @return bool|string
	 */
	public function materialConsumption(): bool|string
	{
		$date = $this->post('date');
		if (!empty($date)) {
			$timeArr = explode(' ~ ', $date);
		} else {
			$timeArr[0] = date('Y-m-d', strtotime("-14 day"));
			$timeArr[1] = $this->date;
		}
		$m   = $timeArr[0];
		$res = [];
		while ($m <= $timeArr[1]) {
			$result   = find(array("table" => "machining_order_detail as a join machining_order as b on a.orderId = b.id join material as c on c.id = a.materialId", "field" => "a.*,b.orderNo,date(b.time) as recordDate,b.lineId,b.type,c.code,c.name as materialName,c.model", "where" => " a.coid = '" . self::$coid . "' and b.state = '已确认' and b.recordDate = '$m' "));
			$standard = 0;
			$actual   = 0;
			foreach ((array)$result['array'] as $array) {
				$material = query('material', "id = '$array[materialId]'", 'buyPrice');
				//领料
				$pickNum      = 0;
				$pickOrderAll = find(array('table' => 'pick_order as a join pick_order_detail as b on a.id = b.orderId', "where" => "a.state = '已确认' and a.type=0 and b.sourceId = '$array[id]' and b.materialSkuId = '$array[materialSkuId]'"));
				foreach ($pickOrderAll['array'] as $val) {
					$inventoryAll = find(array('table' => 'inventory_detail', 'where' => "sourceId = '$val[id]' and num >0 and coid = '" . self::$coid . "'"));
					foreach ($inventoryAll['array'] as $item) {
						$pickNum += machiningOrderClass::material_num_change($array['materialSkuId'], $item['unit'], $array['unit'], $item['num']);
					}
				}
				$pickNum = round($pickNum, 2);
				//退料
				$refundNum      = 0;
				$refundOrderAll = find(array('table' => 'pick_order as a join pick_order_detail as b on a.id = b.orderId', "where" => "a.state = '已确认' and a.type=1 and b.sourceId = '$array[id]' and b.materialSkuId = '$array[materialSkuId]'"));
				foreach ($refundOrderAll['array'] as $val) {
					$inventoryAll = find(array('table' => 'inventory_detail', 'where' => "sourceId = '$val[id]' and num >0 and coid = '" . self::$coid . "'"));
					foreach ($inventoryAll['array'] as $item) {
						$refundNum += machiningOrderClass::material_num_change($array['materialSkuId'], $item['unit'], $array['unit'], $item['num']);
					}
				}
				$refundOrderAll = find(array('table' => 'pick_order as a join pick_order_detail as b on a.id = b.orderId', "where" => "a.state = '已确认' and a.type=1 and b.sourceId in (select id from pick_order_detail where sourceId = '$array[id]') and b.materialSkuId = '$array[materialSkuId]'"));
				foreach ($refundOrderAll['array'] as $val) {
					$refundNum += machiningOrderClass::material_num_change($array['materialSkuId'], $val['unit'], $array['unit'], $val['num']);
				}
				$refundNum = round($refundNum, 2);
				
				//配料
				$disNum = 0;
				$all    = find(array('table' => 'material_distribute_num as a join material_distribute as b on a.orderId = b.id', 'field' => "a.*", 'where' => "b.state = '已确认' and a.materialSkuId = '$array[materialSkuId]' and machiningOrderMxId = '$array[targetSkuId]'"));
				foreach ($all['array'] as $val) {
					$disNum += machiningOrderClass::material_num_change($array['materialSkuId'], $val['unit'], $array['unit'], $val['num']);
				}
				$standard = $array['quantity'] * $material['buyPrice'];
				$actual   = ($pickNum + $disNum - $refundNum - $array['quantity']) * $material['buyPrice'];
			}
			$res[] = [
				'date'     => date("m月d日", strtotime($m)),
				'standard' => round($standard / 10000, 2),
				'actual'   => round($actual / 10000, 2),
			];
			$m     = date("Y-m-d", strtotime($m . " +1 day"));
		}
		$data         = [
			"subtext" => '单位：万元',
			"name"    => array_column($res, 'date'),
			"series"  => [
				[
					'name' => '标准用量',
					'data' => array_column($res, 'standard'),
				],
				[
					'name' => '实际耗用',
					'data' => array_column($res, 'actual'),
				],
			],
		];
		$json['html'] = $this->curve($data, 'area');
		return json_encode($json, 320);
	}
	
	/**
	 * 计时计件工资 - 返回数据
	 */
	public function wage(): bool|string
	{
		$date = $this->post('date');
		if (!empty($date)) {
			$timeArr = explode(' ~ ', $date);
		} else {
			$timeArr[0] = date('Y-m-d', strtotime("-14 day"));
			$timeArr[1] = $this->date;
		}
		
		$arr = find(array("table" => "team", "field" => "id,name", "where" => " coid = '" . self::$coid . "' and state = '启用' "));
		$res = [];
		foreach ((array)$arr['array'] as $index => $val) {
			$pieceMoney = 0;
			$timeMoney  = 0;
			//计件工资
			$result_piece = find(array("table" => "process_report_staff as a join process_report as b on a.orderId = b.id join machining_send_order as ma on ma.id = b.sendId", "field" => "b.*,a.stid as teamStid,ma.unit as fromUnit,ma.machiningOrderMxId,ma.orderNo as sendNo", "where" => " b.classify = '工序报工' and b.coid = '" . self::$coid . "' and b.state = '已确认' and b.teamId = '$val[id]' and teamNo >= '$timeArr[0]' and teamNo <= '$timeArr[1]' "));
			foreach ((array)$result_piece['array'] as $array) {
				$material        = query('material', "id = '$array[materialId]'");
				$routMx          = query('routing_detail', "id = '$array[routingMxId]'");
				$routMx['price'] = $routMx['price'] ?: 0;
				$array['yield']  = machiningOrderClass::material_num_change($array['materialSkuId'], $array['fromUnit'], $material['unit'], $array['yield']);
				$pieceMoney      += $routMx['price'] * $array['yield'];
			}
			//计时工资
			$result_time = find(array("table" => "timing_report", "field" => "distinct recordDate,teamId,staffId", "where" => " coid = '" . self::$coid . "' and teamId = '$val[id]' and recordDate >= '$timeArr[0]' and recordDate <= '$timeArr[1]' "));
			foreach ((array)$result_time['array'] as $array) {
				$hour      = find(array('table' => 'timing_report', 'where' => "recordDate = '$array[recordDate]' and teamId = '$array[teamId]' and staffId = '$array[staffId]' and coid = '" . self::$coid . "'", 'sum' => "hour"));
				$teamMx    = query('team_detail', "orderId = '$array[teamId]' and stid = '$array[staffId]'");
				$timeMoney += $hour * $teamMx['price'];
			}
			$res[] = [
				'text'       => $val['name'],
				'pieceMoney' => round($pieceMoney / 10000, 2),
				'timeMoney'  => round($timeMoney / 10000, 2),
			];
		}
		$data         = [
			"subtext" => '单位：万元',
			"name"    => array_column($res, 'text'),
			"series"  => [
				[
					'name' => '计件工资',
					'data' => array_column($res, 'pieceMoney'),
				],
				[
					'name' => '计时工资',
					'data' => array_column($res, 'timeMoney'),
				],
			],
		];
		$json['html'] = $this->barCharts($data);
		return json_encode($json, 320);
	}
	
	public function produceData(): bool|string
	{
		$json['result'] = [
			/**********左侧********/
			[
				'type'   => 'group',
				'id'     => 'letfGroup',
				'name'   => '',
				'x'      => 50,
				'y'      => 75,
				'width'  => 750,
				'height' => 750,
			],
			$this->nodeData(['page' => 'saleOrder', 'x' => 75, 'y' => 400, 'name' => '销售订单', 'file' => 'produce']),
			$this->nodeData(['page' => 'machiningOrder', 'x' => 225, 'y' => 400, 'name' => '生产计划', 'file' => 'produce']),
			$this->nodeData(['page' => 'semiMachiningOrder', 'x' => 375, 'y' => 400, 'name' => '半成品加工单', 'file' => 'produce']),
			$this->nodeData(['page' => 'workshopClock', 'x' => 525, 'y' => 400, 'name' => '车间考勤表', 'file' => 'produce']),
			$this->nodeData(['page' => 'pieceCount', 'x' => 675, 'y' => 400, 'name' => '计件工资', 'file' => 'produce']),
			$this->nodeData(['page' => 'outsourceSendOrder', 'x' => 375, 'y' => 100, 'name' => '委外派工单', 'file' => 'produce']),
			$this->nodeData(['page' => 'machiningSendOrder', 'x' => 375, 'y' => 250, 'name' => '生产派工单', 'file' => 'produce']),
			$this->nodeData(['page' => 'pickOrder', 'x' => 375, 'y' => 550, 'name' => '领料单', 'file' => 'produce']),
			$this->nodeData(['page' => 'ingredientsOrder', 'x' => 375, 'y' => 700, 'name' => '配料单', 'file' => 'produce']),
			$this->nodeData(['page' => 'outProcessReport', 'x' => 525, 'y' => 100, 'name' => '委外报工单', 'title' => '委外报工', 'file' => 'produce']),
			$this->nodeData(['page' => 'processReport', 'x' => 525, 'y' => 250, 'name' => '生产报工单', 'title' => '工序报工', 'file' => 'produce']),
			$this->nodeData(['page' => 'refundMaterialOrder', 'x' => 525, 'y' => 550, 'name' => '退料单', 'file' => 'produce']),
			$this->nodeData(['page' => 'tempInventory', 'x' => 525, 'y' => 700, 'name' => '线边库存', 'file' => 'produce']),
			$this->nodeData(['page' => 'scrappedOrder', 'x' => 675, 'y' => 100, 'name' => '报废申请单', 'file' => 'produce']),
			$this->nodeData(['page' => 'machiningInOrder', 'x' => 675, 'y' => 250, 'name' => '生产入库单', 'file' => 'produce']),
			$this->nodeData(['page' => 'materialDistribute', 'x' => 675, 'y' => 700, 'name' => '材料倒冲', 'file' => 'produce']),
			/**********右侧********/
			[
				'type'   => 'group',
				'id'     => 'rightUpGroup',
				'name'   => '',
				'x'      => 920,
				'y'      => 75,
				'width'  => 270,
				'height' => 270,
			],
			[
				'type'   => 'group',
				'id'     => 'rightDownGroup',
				'name'   => '',
				'x'      => 920,
				'y'      => 390,
				'width'  => 270,
				'height' => 430,
			],
			$this->nodeData(['page' => 'processingInspection', 'x' => 945, 'y' => 100, 'name' => '制程检验', 'file' => 'produce']),
			$this->nodeData(['page' => 'materialInspection', 'x' => 945, 'y' => 250, 'name' => '来料检验', 'file' => 'produce']),
			$this->nodeData(['page' => 'equipment', 'x' => 945, 'y' => 400, 'name' => '设备', 'file' => 'produce']),
			$this->nodeData(['page' => 'parts', 'x' => 945, 'y' => 550, 'name' => '配件', 'file' => 'produce']),
			$this->nodeData(['page' => 'mold', 'x' => 945, 'y' => 700, 'name' => '模具', 'file' => 'produce']),
			$this->nodeData(['page' => 'processSpotCheck', 'x' => 1095, 'y' => 100, 'name' => '工序巡检', 'file' => 'produce']),
			$this->nodeData(['page' => 'outsourceInspection', 'x' => 1095, 'y' => 250, 'name' => '委外检验', 'title' => '委外入库检验', 'file' => 'produce']),
			$this->nodeData(['page' => 'equipmentInspection', 'x' => 1095, 'y' => 400, 'name' => '巡检', 'file' => 'produce']),
			$this->nodeData(['page' => 'equipmentMaintenance', 'x' => 1095, 'y' => 550, 'name' => '保养', 'file' => 'produce']),
			$this->nodeData(['page' => 'equipmentRepair', 'x' => 1095, 'y' => 700, 'name' => '维修', 'file' => 'produce']),
		];
		$json['link']   = [
			//group link
			//node link
			['source' => 'saleOrder', 'target' => 'machiningOrder', 'vertices' => []],
			['source' => 'machiningOrder', 'target' => 'semiMachiningOrder', 'vertices' => []],
			['source' => 'semiMachiningOrder', 'target' => 'pickOrder', 'vertices' => []],
			['source' => 'semiMachiningOrder', 'target' => 'machiningSendOrder', 'vertices' => []],
			['source' => 'machiningSendOrder', 'target' => 'outsourceSendOrder', 'vertices' => []],
			['source' => 'machiningOrder', 'target' => 'outsourceSendOrder', 'vertices' => [['x' => 260, 'y' => 140]]],
			['source' => 'machiningOrder', 'target' => 'machiningSendOrder', 'vertices' => [['x' => 260, 'y' => 290]]],
			['source' => 'machiningOrder', 'target' => 'pickOrder', 'vertices' => [['x' => 260, 'y' => 590]]],
			['source' => 'machiningOrder', 'target' => 'ingredientsOrder', 'vertices' => [['x' => 260, 'y' => 740]]],
			['source' => 'outsourceSendOrder', 'target' => 'outProcessReport', 'vertices' => []],
			['source' => 'outProcessReport', 'target' => 'processReport', 'vertices' => []],
			['source' => 'processReport', 'target' => 'machiningInOrder', 'vertices' => []],
			['source' => 'machiningInOrder', 'target' => 'scrappedOrder', 'vertices' => []],
			['source' => 'machiningSendOrder', 'target' => 'processReport', 'vertices' => []],
			['source' => 'processReport', 'target' => 'workshopClock', 'vertices' => []],
			['source' => 'workshopClock', 'target' => 'pieceCount', 'vertices' => []],
			['source' => 'pickOrder', 'target' => 'refundMaterialOrder', 'vertices' => []],
			['source' => 'refundMaterialOrder', 'target' => 'tempInventory', 'vertices' => []],
			['source' => 'ingredientsOrder', 'target' => 'tempInventory', 'vertices' => []],
			['source' => 'tempInventory', 'target' => 'materialDistribute', 'vertices' => []],
		];
		return json_encode($json, 320);
	}
	
	private function style(): string
	{
		return <<<eof
<style>
.chart-title{font-size: 14px;font-weight: 700;padding: 0 10px;}
::-webkit-scrollbar-corner {background-color: #fff;}
.m-t-0 {margin: 0 5px 5px 5px!important;}
.chart-widget{background-color: #fff;padding: 8px 5px;margin: 5px 5px;min-height: 180px;overflow-y: auto;}

.title-card-li-content{
  text-align: center;padding-top: 50px
}
.title-card-li-money{
  font-size: 28px;font-weight: bold
}
#body{background-color:#f2f2f2;padding:0 10px}
.right-box-ul{
    height: 500px;
    max-height: none;
}
 .right-box-title{
    display: flex;
 }
 .right-text{
    height: auto;
 }
 .right-box-title li{
    float: left;margin: 5px 10px;min-width: 70px;text-align: center;
 }
 .data-widget-select{
    margin-right: 10px;
 }
 .data-widget-select .fs-label{
     height: 15px;line-height: 15px;
 }
 .data-widget-select .fs-label-wrap{
     border-radius: 4px;
 }
 .aim-rank li{
    margin: 5px 0;
 }
 .aim-rank .right-box-title li:nth-child(1){min-width: 40px}
 .aim-rank .right-box-title li:nth-child(2){min-width: 50px}
 .aim-rank .right-box-title li:nth-child(3){min-width: 100px}
 .aim-rank .right-box-title li:nth-child(4){min-width: 100px}
</style>
eof;
	}
	
	/**
	 * 客户管理主页
	 */
	private function clientHomePage(): string
	{
		// 搜索文本框
		$searchTxt         = self::searchText(array('name' => 'staffName', 'click' => "cardSearch()", 'title' => '员工', 'search' => true)) .
		                     hidden(array('name' => 'stid', 'value' => '')) .
		                     self::searchText([
			                     'click'   => "cardSearch()",
			                     'search'  => true,
			                     "name"    => "month",
			                     "title"   => "时间段",
			                     "class"   => "line28",
			                     "value"   => date('Y-m'),
			                     'laydate' => ['type' => 'month'],
		                     ]);
		$record            = query('user_setting', "stid = '" . self::$stid . "' and type = '销售业绩统计'");
		$setting           = (array)json_decode($record['value'], true);
		$board             = in_array('board', $setting) ? 'display:block;' : 'display:none;';
		$performance_goals = in_array('performance_goals', $setting) ? 'display:block;' : 'display:none;';
		$payment           = in_array('payment', $setting) ? 'display:block;' : 'display:none;';
		$contract_money    = in_array('contract_money', $setting) ? 'display:block;' : 'display:none;';
		$kpi_analysis      = in_array('kpi_analysis', $setting) ? 'display:block;' : 'display:none;';
		$losing_analysis   = in_array('losing_analysis', $setting) ? 'display:block;' : 'display:none;';
		$salesPerformance  = new salesPerformanceStatisticsClass();
		return <<<eof
<div class="home-warp">
    <div class="left-box">
        <div class="chart-widget">
            <p class="chart-title">业务流程图</p>
            <div id="container" class="canvas"></div>
        </div>
    </div>
    <div class="right-box">
        <div class="data-widget">
            {$this->backlog()}
        </div>
        <div style="overflow: hidden">
            <div class="data-widget">
                {$this->message()}
            </div>
        </div>
    </div>
    <div class="data-widget left m-t-0" style="width: 96.6%;{$board}">
        <form name="data-card"><span class="title-card">数据看板</span>{$searchTxt}</form>
        <ul class="revenue">
            <li class="quarter left vertical-line">
                <div class="title-card-li-content" id="contractMoneyHtml">
                   <div>合同金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                <div class="title-card-li-content" id="backMoneyHtml">
                   <div>回款金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
                 <div class="title-card-li-content" id="remindMoneyHtml">
                   <div>剩余应收金额</div>
                   <div><span class="title-card-li-money">￥0.00</span><span>万</span></div>
                </div>
            </li>
            <li class="quarter left vertical-line">
             <div class="title-card-li-content" id="completeRateHtml">
                   <div>目标完成率</div>
                   <div><span class="title-card-li-money">0%</span><span></span></div>
                </div>
            </li>
        </ul>
    </div>
    <div class="data-widget left" style="width: 96.6%;{$performance_goals}">
        {$salesPerformance->dataBoard(['title' => '业绩目标完成情况', 'fun' => 'targetAim', 'startDate' => date('Y-m', strtotime("-12 month")), 'endDate' => date('Y-m')])}
    </div>
    <div class="half left data-widget" style="{$payment}">
       {$salesPerformance->dataBoard(['title' => '计划回款与实际回款', 'fun' => 'planAndFact', 'startDate' => date('Y-m', strtotime("-12 month")), 'endDate' => date('Y-m')])}
    </div>
    <div class="half left data-widget" style="{$contract_money}">
        {$salesPerformance->dataBoard(['title' => '商机金额与合同金额', 'fun' => 'contractAndOpportunity', 'startDate' => date('Y-m', strtotime("-12 month")), 'endDate' => date('Y-m')])}
    </div>
    <div class="half left data-widget" style="{$kpi_analysis}">
        {$salesPerformance->dataBoard(['title' => '关键指标分布', 'fun' => 'kpiData'])}
    </div>
    <div class="half left data-widget" style="{$losing_analysis}">
        {$salesPerformance->dataBoard(['title' => '输单原因分析', 'fun' => 'loseAnalysis'])}
    </div>
</div>
{$this->flowChart('container', 'clientData')}
<script src='{$this->root}static/javascript/echarts.min.js'></script>
<script>
function search_line(formName,cla,fun) {
     $("#" + fun + "Html").html("数据查询中，请稍后。。。");
    $.post(root + "control/adIndex.html?cla=salesPerformanceStatistics&fun=" + fun, $("[name='" + formName + "']").serialize(), function (data) {
         $("#" + fun + "Html").html(data.html);
    }, "json");
}


/**
* 看板搜索
*/
function cardSearch(){
      ['contractMoney', 'backMoney', 'remindMoney', 'completeRate'].forEach((fun)=>{
                    search_line('data-card','salesPerformanceStatistics', fun)
    })
}

$(function() {
    ['contractMoney', 'backMoney', 'remindMoney', 'completeRate'].forEach((fun)=>{
                    search_line('data-card','salesPerformanceStatistics', fun)
    });
    search_line('aimRankForm','salesPerformanceStatistics','aimRank');
    search_line('signRankForm','salesPerformanceStatistics','signRank')
    $("[name='staffName']").each(function (){
          $(this).bigAutocomplete({
            url:root + 'control/adIndex.html?cla=component&fun=getStaff',
            callback:function(data,e){
                console.log(data.id);
                e.parent().siblings("input[name='stid']").val(data.id)
        }})
    })
})
</script>
eof;
	}
	
	/**
	 * 商机金额与合同金额
	 *
	 * @return string
	 */
	public function opportunity(): string
	{
		$months = $this->post('months');
		if (!empty($months)) {
			$timeArr = explode(' ~ ', $months);
		} else {
			$timeArr[0] = date('Y-m', strtotime("-11 month"));
			$timeArr[1] = date('Y-m');
		}
		$staffId        = $this->post('staffId');
		$opportunityAnd = $contractAnd = "";
		if ($staffId) {
			$opportunityAnd .= " and manager = '$staffId' ";
			$contractAnd    = " and salesman = '$staffId' ";
		}
		$m   = $timeArr[0];
		$res = [];
		while ($m <= $timeArr[1]) {
			$res[] = [
				'month'         => $m,
				'opportunity'   => find([
						'table'  => "opportunity",
						'field'  => "IFNULL(sum(exSaleMoney),0) as total",
						'single' => " 1=1 and date_format(exSignDate, '%Y-%m') = '$m' " . $opportunityAnd,
					])['total'] ?? 0,
				'contractMoney' => find([
						'table'  => "sales_contract",
						'field'  => "IFNULL(sum(money),0) as total",
						'single' => " state = '已通过' and date_format(signedDate, '%Y-%m') = '$m' " . $contractAnd,
					])['total'] ?? 0,
			];
			$m     = date("Y-m", strtotime($m . "-01 +1 month"));
		}
		
		$data         = [
			"name"   => array_column($res, 'month'),
			"series" => [
				[
					'name' => '商机',
					'data' => array_column($res, 'opportunity'),
				],
				[
					'name' => '合同',
					'data' => array_column($res, 'contractMoney'),
				],
			],
		];
		$json['html'] = $this->curve($data, 'area');
		return json_encode($json, 320);
	}
	
	/**
	 * 离职趋势 数据
	 *
	 * @return string
	 */
	public function collectionStatus(): string
	{
		$months = $this->post('months');
		if (!empty($months)) {
			$timeArr = explode(' ~ ', $months);
		} else {
			$timeArr[0] = date('Y-m', strtotime("-11 month"));
			$timeArr[1] = date('Y-m');
		}
		$staffId    = $this->post('staffId');
		$paymentAnd = $contractAnd = "";
		if ($staffId) {
			$paymentAnd  .= " and managerId = '$staffId' ";
			$contractAnd = " and salesman = '$staffId' ";
		}
		$m   = $timeArr[0];
		$res = [];
		while ($m <= $timeArr[1]) {
			$plan   = find([
				'table'  => "sales_contract_payback",
				'field'  => "IFNULL(sum(money),0) as total",
				'single' => " orderId in (select id from sales_contract where state = '已通过' {$contractAnd}) and date_format(date, '%Y-%m') = '$m' ",
			])['total'] ?? 0;
			$actual = find([
				'table'  => "payment",
				'field'  => "IFNULL(sum(money),0) as total",
				'single' => " state = '已通过' and classify = 2 and targetId in (select id from sales_contract where state = '已通过') and date_format(recordDate, '%Y-%m') = '$m' " . $paymentAnd,
			])['total'] ?? 0;
			$res[]  = [
				'month'  => $m,
				'plan'   => $plan,
				'actual' => $actual,
			];
			$m      = date("Y-m", strtotime($m . "-01 +1 month"));
		}
		$data         = [
			"name"   => array_column($res, 'month'),
			"series" => [
				[
					'name' => '计划回款',
					'data' => array_column($res, 'plan'),
				],
				[
					'name' => '实际回款',
					'data' => array_column($res, 'actual'),
				],
			],
		];
		$json['html'] = $this->curve($data);
		return json_encode($json, 320);
	}
	
	/**
	 * 业绩目标完成情况 - 返回数据
	 */
	public function performanceCompletion(): bool|string
	{
		$months = $this->post('months');
		if (!empty($months)) {
			$timeArr = explode(' ~ ', $months);
		} else {
			$timeArr[0] = date('Y-m', strtotime("-11 month"));
			$timeArr[1] = date('Y-m');
		}
		$staffId   = $this->post('staffId');
		$targetAnd = $contractAnd = "";
		if ($staffId) {
			$targetAnd   = " and staffId like '%$staffId%' ";
			$contractAnd = " and salesman = '$staffId' ";
		}
		$m   = $timeArr[0];
		$res = [];
		while ($m <= $timeArr[1]) {
			$res[] = [
				'month'         => $m,
				'target'        => find([
						'table'  => "performance_target",
						'field'  => "IFNULL(sum(money),0) as total",
						'single' => " month = '$m' " . $targetAnd,
					])['total'] ?? 0,
				'contractMoney' => find([
						'table'  => "sales_contract",
						'field'  => "IFNULL(sum(money),0) as total",
						'single' => " state = '已通过' and date_format(signedDate, '%Y-%m') = '$m' " . $contractAnd,
					])['total'] ?? 0,
			];
			$m     = date("Y-m", strtotime($m . "-01 +1 month"));
		}
		$data         = [
			"name"   => array_column($res, 'month'),
			"series" => [
				[
					'name' => '目标',
					'data' => array_column($res, 'target'),
				],
				[
					'name' => '合同金额',
					'data' => array_column($res, 'contractMoney'),
				],
			],
		];
		$json['html'] = $this->barCharts($data);
		return json_encode($json, 320);
	}
	
	
	/**
	 * 客户管理数据看板
	 *
	 * @return string
	 */
	public function contractData(): string
	{
		//总营收 = 销售收入
		$month       = $this->post('month') ?: date('Y-m') . ' ~ ' . date('Y-m');
		$staffId     = $this->post('staffId');
		$contractAnd = $paymentAnd = $targetAnd = "";
		if ($staffId) {
			$contractAnd .= " and salesman = '$staffId' ";
			$paymentAnd  .= " and managerId = '$staffId' ";
			$targetAnd   .= " and staffId like '%$staffId%' ";
		}
		$contract_money = find([
			'table'  => "sales_contract",
			'field'  => "IFNULL(sum(money),0) as total",
			'single' => " state = '已通过' " . $contractAnd . $this->timeComparison($month, 'month', 'signedDate'),
		])['total'] ?? 0;
		$payment        = find([
			'table'  => "payment",
			'field'  => "IFNULL(sum(money),0) as total",
			'single' => " state = '已通过' and classify = 2 and targetId in (select id from sales_contract where state = '已通过') " . $paymentAnd . $this->timeComparison($month, 'month', 'recordDate'),
		])['total'] ?? 0;
		$surplus_money  = $contract_money - $payment;
		$data           = explode('~', $month);
		$start          = trim($data[0]);
		$end            = trim(end($data));
		$target         = find([
			'table'  => "performance_target",
			'field'  => "IFNULL(sum(money),0) as total",
			'single' => " month between '$start' and '$end' " . $targetAnd,
		])['total'] ?? 0;
		$completionRate = $target == 0 ? 0 : round($contract_money / $target * 100, 2);
		$json['html']   = <<<EOT
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">合同金额</p>
                <p class="hr-p f-30">$contract_money</p>
            </div>
        </li>
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">回款金额</p>
                <p class="hr-p f-30">$payment</p>
            </div>
        </li>
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">剩余应收金额</p>
                <p class="hr-p f-30">$surplus_money</p>
            </div>
        </li>
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">目标完成率</p>
                <p class="hr-p f-30">$completionRate%</p>
            </div>
        </li>
EOT;
		return json_encode($json, 320);
	}
	
	/** 业务流程图
	 *
	 * @param string $id
	 * @param string $fun
	 * @return bool|string
	 */
	public function flowChart(string $id, string $fun): bool|string
	{
		return <<<eof
<script src="{$this->root}static/javascript/x6.js"></script>
<script>
 X6.Graph.registerNode(
  'org-node',
  {
    width: 70,
    height: 80,
    markup: [
      {
        tagName: 'rect',
        selector: 'body',
      },
      {
        tagName: 'image',
        selector: 'avatar',
      },
      {
        tagName: 'text',
        selector: 'name',
      },
    ],
    attrs: {
      body: {
        refWidth: '100%',
        refHeight: '100%',
        fill: 'transparent',
        stroke: 'transparent',
        strokeWidth: 1,
        rx: 10,
        ry: 10,
        pointerEvents: 'visiblePainted',
      },
      avatar: {
        width: 48,
        height: 48,
        refX: '15%',
        refY: '8%',
      },
      name: {
        refX: '50%',
        refY: '85%',
        fill: '#333',
        fontFamily: 'Courier New',
        fontSize: 14,
        textAnchor: 'middle',
        textVerticalAnchor: 'middle',
      },
    },
  },
  true,
)
X6.Graph.registerEdge(
  'org-edge',
  {
    inherit: 'edge',
    attrs: {
      line: {
        strokeWidth: 1,
        stroke: '#aaa',
        strokeDasharray: '2,3',
      },
    },
  },
  true,
)

const graph = new X6.Graph({
  height: 1062,
  container: document.getElementById('{$id}'),
  connecting: {
    anchor: 'orth',
  },
  background: {
    color: '#fff', // 设置画布背景颜色
  },
  interacting: {
    nodeMovable: false
  },
  scroller: {
    enabled: true,
    pannable: true,
  },
  mousewheel: {
    enabled: true,
    modifiers: ['ctrl', 'meta'],
  },
})
function member(item) {
  return graph.addNode({
    x:item.x,
    y:item.y,
    shape: 'org-node',
    attrs: {
        data:{
            title:item.title,
            name:item.name,
            url:item.url,
            power:item.power
        },
        avatar: {
            opacity: 0.7,
            'xlink:href': item.img,
        },
        name: {
            text: item.name,
            wordSpacing: '-10px',
            letterSpacing: 0,
        },
    },
  })
}

function groupMember(item) {
  return graph.addNode({
    x:item.x,
    y:item.y,
    width: item.width,
    height: item.height,
    zIndex: 1,
    label: item.name,
    attrs: {
        label: {
            refY: '50%'
        },
        body: {
          fill: "transparent",
          stroke: "#aaa",
          strokeDasharray: "3,2",
          strokeWidth: 1,
        }
    }
  })
}

function link(item) {
  return graph.addEdge({
    vertices: item.vertices,
    source: {
      cell: node[item.source],
    },
    target: {
      cell: node[item.target],
    },
    shape: 'org-edge',
  })
}
const node = {}
function loopData(result) {
    result.forEach((item,index)=>{
        if (item){
            if(item.type === 'node'){
                node[item.id] = member(item)
            }else{
                node[item.id] = groupMember(item)
            }
        }
    })
}
function linkData(result) {
    result.forEach((item,index)=>{
        if (item){
            link(item)
        }
    })
}
function requestData(){
    $.post(root+'control/adIndex.html?cla=homepage&fun={$fun}',{},function(res) {
        loopData(res.result);
        linkData(res.link);
        addEvent();
    },'json')
}

function addEvent(){
    graph.on('node:click', ({ e, x, y, node, view }) => {
        if (node.attrs.data.power){
            newIframe(node.attrs.data.title,node.attrs.data.url)
        }else{
            msg('您还没有此页面的查看权限','error')
        }
    })
}
requestData();

</script>
eof. $this->style();
	}
	
	public function clientData(): bool|string
	{
		$json['result'] = [
			$this->nodeData(['page' => 'cluePool', 'x' => 250, 'y' => 70, 'name' => '线索池', 'file' => 'client']),
			$this->nodeData(['page' => 'clue', 'x' => 400, 'y' => 70, 'name' => '线索', 'file' => 'client']),
			$this->nodeData(['page' => 'client', 'x' => 400, 'y' => 220, 'name' => '客户', 'file' => 'client']),
			$this->nodeData(['page' => 'kehuStaff', 'x' => 550, 'y' => 220, 'name' => '联系人', 'file' => 'client']),
			$this->nodeData(['page' => 'follow', 'x' => 700, 'y' => 220, 'name' => '跟进记录', 'file' => 'client']),
			$this->nodeData(['page' => 'clientPool', 'x' => 250, 'y' => 220, 'name' => '公客池', 'file' => 'client']),
			$this->nodeData(['page' => 'visitPlan', 'x' => 700, 'y' => 70, 'name' => '拜访记录', 'title' => '访客计划', 'file' => 'client']),
			$this->nodeData(['page' => 'opportunity', 'x' => 400, 'y' => 370, 'name' => '商机', 'file' => 'client']),
			$this->nodeData(['page' => 'programme', 'x' => 550, 'y' => 370, 'name' => '方案评审', 'file' => 'client']),
			$this->nodeData(['page' => 'quotations', 'x' => 700, 'y' => 370, 'name' => '报价单', 'file' => 'client']),
			$this->nodeData(['page' => 'salesContract', 'x' => 400, 'y' => 520, 'name' => '合同', 'title' => '销售合同', 'file' => 'client']),
			$this->nodeData(['page' => 'paybackRecord', 'x' => 250, 'y' => 670, 'name' => '回款记录', 'file' => 'client']),
			$this->nodeData(['page' => 'paybackPlan', 'x' => 250, 'y' => 520, 'name' => '回款计划', 'file' => 'client']),
			$this->nodeData(['page' => 'invoice', 'x' => 400, 'y' => 670, 'name' => '开票记录', 'file' => 'client']),
		];
		$json['link']   = [
			['source' => 'cluePool', 'target' => 'clue', 'vertices' => []],
			['source' => 'clue', 'target' => 'client', 'vertices' => []],
			['source' => 'client', 'target' => 'kehuStaff', 'vertices' => []],
			['source' => 'client', 'target' => 'opportunity', 'vertices' => []],
			['source' => 'kehuStaff', 'target' => 'follow', 'vertices' => []],
			['source' => 'kehuStaff', 'target' => 'visitPlan', 'vertices' => [['x' => 670, 'y' => 260], ['x' => 670, 'y' => 100]]],
			['source' => 'clientPool', 'target' => 'client', 'vertices' => []],
			['source' => 'opportunity', 'target' => 'programme', 'vertices' => []],
			['source' => 'opportunity', 'target' => 'salesContract', 'vertices' => []],
			['source' => 'programme', 'target' => 'quotations', 'vertices' => []],
			['source' => 'invoice', 'target' => 'paybackRecord', 'vertices' => []],
			['source' => 'paybackPlan', 'target' => 'paybackRecord', 'vertices' => []],
			['source' => 'salesContract', 'target' => 'invoice', 'vertices' => []],
			['source' => 'salesContract', 'target' => 'paybackPlan', 'vertices' => []],
			['source' => 'quotations', 'target' => 'salesContract', 'vertices' => [['x' => 735, 'y' => 560]]],
		];
		return json_encode($json, 320);
	}
	
	/**
	 * 人力资源管理主页
	 */
	private function personnelHomePage(): string
	{
		$moreIco = root . 'img/control/more.svg';
		// 搜索文本框
		$searchTxt =
			"<span class=\"search-ico right\" onclick=\"getData()\"></span>"
			. text([
				'name'    => 'dataBoardDate',
				'title'   => "时间段",
				"class"   => "text text-data right contour width200",
				"value"   => date('Y-m') . '-01 ~ ' . date('Y-m-d'),
				'laydate' => ['range' => '~', 'type' => 'date',],
			]) .
			selectMultiple(["name" => "dataBoardDepartmentId", 'table' => " department", 'class' => " text right contour width200", 'sqlId' => 'id', 'sqlField' => 'name', 'title' => '部门']);
		
		return <<<EOT
        <div class="home-warp">
            <div class="left-box">
                <div class="quick-entry data-widget">
                    {$this->quickEntry()}
                </div>
                 <div class="data-widget">
                    <p><span class="title-card">数据看板</span>$searchTxt</p>
                    <ul class="revenue-hr" id="hrDataHtml">
                    
                    </ul>
                </div>
                <div class="data-widget left" style="width: 97.4%;">
                    {$this->dataBoardDate(['title' => '入职、离职趋势', 'fun' => 'entryQuitTrend'])}
                </div>
                <div class="half left data-widget">
                    {$this->dataBoardDate(['title' => '入职、离职人员部门分布', 'fun' => 'depDistribute'])}
                </div>
                <div class="half left data-widget">
                    {$this->dataBoardDate(['title' => '离职率趋势', 'fun' => 'turnoverRate'])}
                </div>
            </div>
            <div class="right-box">
                <div class="data-widget">
                    {$this->backlog()}
                </div>
                <div style="overflow: hidden">
                    <div class="data-widget">
                        {$this->message()}
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script src='{$this->root}static/javascript/echarts.min.js'></script>
    <script>
        function getData(){
            let date = $('[name="dataBoardDate"]').val(),
                funArray = ['hrData'],
                dataBoardDepartmentId = $('[name="dataBoardDepartmentId"]').val()
            funArray.forEach((fun)=>{
                 $.post(root + 'control/adIndex.html?cla=homepage&fun=' + fun, {date: date,departmentId: dataBoardDepartmentId}, function (res) {
	                 let obj = '#' + fun + 'Html';
	                 $(obj).empty().append(res.html)
                 }, 'json')
            })
        }
        $(function() {
           getData()
        })
    </script>
EOT;
	}
	
	/**
	 * 数据看板
	 *
	 * @param array $data 格式 [ 'title'=>'标题', 'fun'=>'数据源函数', 'condition'=> '显示查询条件，为空表示显示' ]
	 */
	public static function dataBoardDate(array $data): string
	{
		$endDate   = date("Y-m-d");
		$startDate = date("Y-m") . '-01';
		if (isset($data['startDate'])) {
			$startDate = $data['startDate'];
		}
		if (isset($data['endDate'])) {
			$endDate = $data['endDate'];
		}
		$html        = '';
		$isCondition = (!isset($data['condition']) || $data['condition'] !== false);
		if ($isCondition) {
			$dateText = text(["name" => "date", "title" => "时间段", "class" => "text text-data right contour width200", "value" => $startDate . ' ~ ' . $endDate, 'laydate' => ['range' => '~', 'type' => 'date']]) .
			            selectMultiple(["name" => "departmentId", 'table' => " department", 'class' => " text right contour width200", 'sqlId' => 'id', 'sqlField' => 'name', 'title' => '部门']);
			$html     .= <<<EOT
			<form name='{$data['fun']}Form' onsubmit="return searchFormSub('homepage', '{$data['fun']}')">
			    <p>
				<span class="title-card">{$data['title']}</span>
				<span class="search-ico right" onclick="return searchFormSub('homepage', '{$data['fun']}')"></span>
				$dateText
				</p>
			</form>
EOT;
		}
		$isCondition = settype($isCondition, "int");
		$html        .= <<<EOT
<div id='{$data['fun']}Html' class='data-box-show'>数据查询中。。。</div>
EOT;
		if (!in_array($data['title'], ['回款率', '现金占比', '客户来源'])) {
			$html .= <<<eof
            <script>
            $(function(){searchForm('homepage', '{$data['fun']}', 1)})
            </script>
eof;
		}
		//返回
		return $html;
	}
	
	/**
	 * 办公协同主页
	 */
	private function administrationHomePage(): string
	{
		return '';
	}
	
	/**
	 * 默认主页
	 */
	private function defaultHomePage(): string
	{
		$moreIco = root . 'img/control/more.svg';
		// 搜索文本框
		$searchTxt =
			"<span class=\"search-ico right\" onclick=\"getData()\"></span>"
			. text([
				'name'    => 'dataBoardDate',
				'title'   => "时间段",
				"class"   => "text text-data right contour width200",
				"value"   => date('Y-m', strtotime('-1 month')) . ' ~ ' . date('Y-m'),
				'laydate' => ['range' => '~', 'type' => 'month',],
			]);
		return <<<EOT
        <div class="home-warp">
            <div class="left-box">
                <div class="quick-entry data-widget">
                {$this->quickEntry()}
                </div>
                <div class="half left data-widget h-300">
                    <p><span class="title-card">我的任务</span></p>
                    <ul>
                       {$this->myMission()}
                    </ul>
                </div>
                <div class="half left data-widget h-300">
                    <p><span class="title-card">学习园地</span></p>
                    <ul>
                       {$this->learningGarden()}
                    </ul>
                </div>

                <div class="half left data-widget h-300">
                    <p><span class="title-card">公司通知</span></p>
                    <ul>
                       {$this->notificationMessage('公司通知')}
                    </ul>
                </div>
                <div class="half left data-widget h-300">
                    <p><span class="title-card">公司动态</span></p>
                    <ul>
                       {$this->notificationMessage('公司动态')}
                    </ul>
                </div>
            </div>
            <div class="right-box">
                <div class="data-widget">
                    {$this->backlog()}
                </div>
                <div style="overflow: hidden">
                    <div class="data-widget">
                        {$this->message()}
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script src='{$this->root}static/javascript/echarts.min.js'></script>

EOT;
	}
	
	/**
	 * 公司动态和公司通知
	 */
	public function notificationMessage($type): string
	{
		$html = '';
		if ($type == '公司动态') {
			$cla = 'news';
		} else {
			$cla = 'notification';
		}
		$result = find(array('table' => 'message', 'where' => "stid = '{$this->control['stid']}' and type = '$type' and see = '否' order by time asc"));
		foreach ($result['array'] as $array) {
			$html .= "<li onclick=\"window.open('" . root . "control/adIndex.html?cla=$cla&fun=previewPage&source=homepage&id={$array['typeId']}')\">" . $array['text'] . "<span class='time'>" . self::formatDate($array['time']) . "</span></li>";
		}
		if (empty($html)) {
			$html .= "<li class='nodata'>暂无内容</li>";
		}
		return $html;
	}
	
	/**
	 * 我的任务
	 */
	public function myMission(): string
	{
		$html   = '';
		$result = find(array('table' => 'mission', 'where' => "manager = '{$this->control['stid']}' and workFlow <> '已完成' order by time asc"));
		foreach ($result['array'] as $array) {
			$isOverdue = $array['workFlow'] != '已完成' ? (strtotime($array['endTime']) < time() ? "orange" : '') : (strtotime($array['endTime']) < strtotime($array['completeTime']) ? "orange" : '');
			$html      .= "<li onclick=\"newIframe('任务详情','" . root . "control/adIndex.html?cla=mission&fun=detail&id={$array['id']}')\">" . zishu($array['title'], 25) . " <span class='time $isOverdue'>" . self::formatDate($array['endTime']) . "</span></li>";
		}
		if (empty($html)) {
			$html .= "<li class='nodata'>暂无内容</li>";
		}
		return $html;
	}
	
	/**
	 * 学习园地
	 */
	public function learningGarden(): string
	{
		$html          = '';
		$idColloection = $this->staffCombination(true);
		$result        = find(['table' => 'document', 'field' => 'id, title,time', 'where' => " `state` = '已发布' AND ((concat(',',replace(selector,';',','),',') regexp concat(',',replace('{$idColloection}',',',',|,'),','))>0  OR `stid` = '" . self::$stid . "') "]);
		foreach ($result['array'] as $array) {
			$html .= "<li onclick=\"newIframe('文档中心','" . root . "control/adIndex.html?cla=documentCenter&fun=home&id={$array['id']}')\">" . zishu($array['title'], 25) . " <span class='time'>" . self::formatDate($array['time']) . "</span></li>";
		}
		if (empty($html)) {
			$html .= "<li class='nodata'>暂无内容</li>";
		}
		return $html;
	}
	
	
	/**
	 * 获取系统配置下的所有三级菜单
	 */
	public function getThreeAll(): array
	{
		$array = [];
		foreach ((array)$this->powerAll as $twoArray) {
			foreach ((array)$twoArray as $threeArray) {
				unset($threeArray['attribute']);
				foreach ((array)$threeArray as $threeKey => $fourArray) {
					$array[$threeKey] = $fourArray['name'];
				}
			}
		}
		return $array;
	}
	
	/**
	 * 获取当前用户权限的所有三级菜单key
	 *
	 * @return array
	 */
	public function getUserThreeAll(): array
	{
		return array_keys($this->controlPower);
	}
	
	/**
	 * 获取用户配置的快捷入口key
	 *
	 * @return array
	 */
	public static function getUserQuick(): array
	{
		$quick     = [];
		$userQuick = (array)json_decode(self::$user['quick'], 320);
		foreach ($userQuick as $value) {
			foreach ($value as $v) {
				$quick[] = $v;
			}
		}
		return $quick;
	}
	
	public function quickEntry(): string
	{
		$setIco = $this->root . 'img/control/setting.svg';
		// 获取该用户当前权限
		$userPower = $this->getUserThreeAll();
		// 用户快捷入口
		$quick = self::getUserQuick();
		// 权限与实际key交集
		$array = array_intersect($userPower, $quick);
		// 所有三级菜单
		$threeAll = $this->getThreeAll();
		// 构造链接
		$html = '';
		foreach ($array as $key) {
			$title = $threeAll[$key];
			if ($title) {
				$root = $this->root . 'control/adIndex.html?cla=' . $key . '&fun=home';
				$html .= "<li onclick=\"newIframe('$title', '$root')\">$title</li>\n";
			}
		}
		return <<<EOT
        <p><span class="title-card">快捷入口</span> <span class="setting-ico">
        <img src="$setIco" onclick="newIframe('设置快捷入口','{$this->root}control/adIndex.html?cla=homepage&fun=setQuickEntry')" alt=""></span></p>
        <ul>
            $html
        </ul>
EOT;
	}
	
	
	/**
	 * 快捷入口
	 */
	public function setQuickEntry(): string
	{
		//定义参数
		$data = [
			"button" => "更新",
			'power'  => false,
			'onion'  => [
				'主页', '设置快捷入口',
			],
		];
		//权限
		$quick          = [];
		$quickEntryHtml = $one = $h3 = "";
		foreach ($this->powerAll as $oneKey => $twoArray) {
			$secondary = '';
			$title     = $twoBox = '';
			// 过滤未配置的一级菜单
			if ($twoArray) {
				$line = '';
				foreach ($twoArray as $twoKey => $threeArray) {
					unset($threeArray['attribute']);
					$box = '';
					// $checkAll = "checked";
					// 过滤空二级菜单
					if ($threeArray) {
						$valArray = $checked = [];
						// 获取该用户当前权限
						$userPower = $this->getUserThreeAll();
						// 用户配置的快捷入口
						$quick     = self::getUserQuick();
						$threeFlag = false;
						foreach ($threeArray as $threeKey => $fourArray) {
							if (!$fourArray['name'] || !$fourArray) {
								continue;
							}
							// 没有权限跳过
							if (!in_array($threeKey, $userPower)) {
								continue;
							}
							$valArray[$threeKey] = $fourArray['name'];
							// 选中
							if (in_array($threeKey, $quick)) {
								$checked[] = $threeKey;
							}
							$threeFlag = true;
						}
						$box .= checkbox(["name" => "quick[" . $twoKey . "]", "value" => $valArray, "checked" => $checked]);
						// 是否全部选中
						$checkAll = (count($valArray) == count($checked)) ? 'checked' : '';
						// 标题
						$title  = ($twoKey != $secondary) ? '<label class="checkbox"><input value="quick[' . $twoKey . ']" type="checkbox" onchange="checkboxAll(this)"' . $checkAll . '><span></span>' . "\n$twoKey" . '：</label>' : '';
						$twoBox .= ($threeFlag === true) ? ('<div class="secondary-box">' . $title . $box . '</div>') : '';
					}
				}
				$h3             = ($oneKey != $one) ? ('<h3 class="one-title">' . $oneKey . '</h3>') : '';
				$quickEntryHtml .= $twoBox ? ('<div class="box ' . $line . '">' . $h3 . $twoBox . '</div>') : '';
				$line           = "line";//分隔线
			}
		}
		//编辑页表单数组
		$data['tr'] = [
			[
				$quickEntryHtml,
			],
		];
		return $this->tab($data);
	}
	
	/**
	 * 保存设置
	 */
	public function setQuickEntryEdit(): string
	{
		$quick = $this->post('quick');
		if (!$quick) {
			$json['warn'] = "请勾选需要设置的快捷入口";
		} else {
			$json['warn'] = update([
				"table" => "user",
				"field" => [
					'quick' => json_encode($quick, 320),
				],
				"where" => " uid = '" . self::$user['uid'] . "' ",
			]);
			if (in_array($json['warn'], ["新增成功", "更新成功"])) {
				//提示
				$_SESSION['warn'] = "快捷入口设置成功";
				$json['warn']     = 2;
				//返回
				$json['href'] = root . "control/adIndex.html?cla=homepage&fun=home";
			}
		}
		return json_encode($json, 320);
	}
	
	/**
	 * 待办事项
	 */
	public function backlog(): string
	{
		//赋值
		//数据查询
		$result = find(array("table" => "backlog", "where" => " stid = '" . $this->control['stid'] . "' and workFlow = '待处理' order by FIELD(urging,'是','否'),time asc"));
		$ul     = '<ul class="right-box-ul">';
		if (!$result['array']) {
			$ul .= '<li class="nodata">暂无内容</li>';
		} else {
			foreach ($result['array'] as $array) {
				if ($array['startDay'] <= date("Y-m-d")) {
					$info = query('audit', " id ='$array[typeId]'");
					$urge = ($array['urging'] == '是') ? ("<span style='color: red'>[催]</span>") : '';
					if (!empty($array['targetCla']) && !empty($array['targetFun']) && empty($info['id'])) {
						$ul .= "<li onclick=\"newIframe('{$array['type']}详情','" . root . "control/adIndex.html?cla={$array['targetCla']}&fun={$array['targetFun']}&id={$array['typeId']}')\">" . $urge . zishu($array['text'], 16) . " <span class='time'>" . self::formatDate($array['time']) . "</span></li>";
					} elseif ($info['id']) {
						$ul .= "<li onclick=\"newIframe('{$array['type']}详情','" . root . "control/adIndex.html?cla={$info['targetCla']}&fun={$info['targetFun']}&id={$info['targetId']}')\">" . $urge . zishu($array['text'], 16) . " <span class='time'>" . self::formatDate($array['time']) . "</span></li>";
					}
				}
			}
		}
		$ul .= '</ul>';
		// 拼接字符串
		return <<<EOT
        <p><span class="title-card">待办事项</span><span class="more-ico"><img src="{$this->root}img/control/more.svg" onclick="newIframe('待办事项','{$this->root}control/adIndex.html?cla=backlog&fun=home')" alt=""></span></p>
        $ul
EOT;
	}
	
	/**
	 * 菜单搜索
	 *
	 * @return false|string
	 */
	public function menuSearch(): bool|string
	{
		$key          = $this->post('keyword');//关键词
		$result       = $this->getUserMenu($key);
		$json['warn'] = 2;
		$json['data'] = [];
		foreach ($result as $val) {
			$json['data'][] = array('title' => $val['name'], 'menuOneName' => $val['menuOneName'], 'menuTwoName' => $val['menuTwoName'], 'id' => $val['power'], 'url' => $val['url']);
		}
		return json_encode($json, 320);
	}
	
	/**
	 * 获取用户菜单
	 *
	 * @return array
	 */
	public function getUserMenu($key): array
	{
		$menu = [];
		if (is_array($this->powerAll)) {
			$userPower = $this->getUserThreeAll();
			foreach ($this->powerAll as $menuOneName => $menuOne) {
				foreach ($menuOne as $menuTwoName => $menuTwo) {
					foreach ($menuTwo as $menuThreeName => $value) {
						if (in_array($menuThreeName, $userPower) && str_contains($value['name'], $key)) {
							if (empty($value['cla']) or empty($value['fun'])) {
								//如果没有定义类或函数名称，则使用模块名称作为类名称
								$iframeHref = "control/adIndex.html?cla=" . $menuThreeName . "&fun=home";
							} else {
								$iframeHref = "control/adIndex.html?cla=" . $value['cla'] . "&fun=" . $value['fun'];
							}
							$menu[] = [
								'power'       => $menuThreeName,
								'name'        => $value['name'],
								'menuOneName' => $menuOneName,
								'menuTwoName' => $menuTwoName,
								'url'         => $iframeHref,
							];
						}
					}
				}
			}
		}
		return $menu;
	}
	
	/**
	 * 消息中心
	 */
	public function message(): string
	{
		//数据查询
		$message = find(array("table" => "message", "where" => " stid = '" . $this->control['stid'] . "' and type not in ('公司通知','公司动态','预警消息') and see = '否' order by time desc "));
		$ul      = '<ul class="right-box-ul">';
		$i       = 0;
		if ($message['array']) {
			foreach ($message['array'] as $array) {
				$info = query('audit', " id ='$array[typeId]'");
				if (!empty($array['targetCla']) && !empty($array['targetFun']) && empty($info['id'])) {
					$ul .= "<li onclick=\"see('{$array['type']}','{$array['targetCla']}','{$array['targetFun']}','{$array['typeId']}','{$array['id']}')\">" . zishu($array['text'], 18) . " <span class='time'>" . self::formatDate($array['time']) . "</span></li>";
				} else {
					$ul .= "<li onclick=\"see('{$array['type']}','{$info['targetCla']}','{$info['targetFun']}','{$info['targetId']}','{$array['id']}')\">" . zishu($array['text'], 18) . " <span class='time'>" . self::formatDate($array['time']) . "</span></li>";
				}
				$i++;
			}
		}
		if ($i == 0 || !$message['array']) {
			$ul .= '<li class="nodata">暂无内容</li>';
		}
		$ul .= '</ul>';
		// 拼接字符串
		return <<<EOT
        <p><span class="title-card">消息中心</span><span class="more-ico"><img src="{$this->root}img/control/more.svg" onclick="newIframe('消息中心','{$this->root}control/adIndex.html?cla=message&fun=home')" alt=""></span></p>
        $ul
        <script>
        function see(type,targetCla,targetFun,targetId,messageId){
            $.post(root+'control/adIndex.html?cla=homepage&fun=see',{messageId:messageId},function(res) {
               if (res.warn ===2){
                    newIframe(type+'详情',root+'control/adIndex.html?cla='+targetCla+'&fun='+targetFun+'&id='+targetId)
               }else{
                   warn(res.warn);
               }
            },'json')
        }
</script>
EOT;
	}
	
	/**
	 * 预警消息
	 */
	public function alertMessage(): string
	{
		//数据查询
		$message = find(array("table" => "message", "where" => " stid = '" . $this->control['stid'] . "' and type = '预警消息' and see = '否' order by time desc "));
		$ul      = '<ul class="right-box-ul">';
		$i       = 0;
		if ($message['array']) {
			foreach ($message['array'] as $array) {
				$info = query('audit', " id ='$array[typeId]'");
				if (!empty($array['targetCla']) && !empty($array['targetFun']) && empty($info['id'])) {
					$ul .= "<li onclick=\"see('{$array['type']}','{$array['targetCla']}','{$array['targetFun']}','{$array['typeId']}','{$array['id']}')\">" . zishu($array['text'], 18) . " <span class='time'>" . self::formatDate($array['time']) . "</span></li>";
				} else {
					$ul .= "<li onclick=\"see('{$array['type']}','{$info['targetCla']}','{$info['targetFun']}','{$info['targetId']}','{$array['id']}')\">" . zishu($array['text'], 18) . " <span class='time'>" . self::formatDate($array['time']) . "</span></li>";
				}
				$i++;
			}
		}
		if ($i == 0 || !$message['array']) {
			$ul .= '<li class="nodata">暂无内容</li>';
		}
		$ul .= '</ul>';
		// 拼接字符串
		return <<<EOT
        <p><span class="title-card">预警消息</span></p>
        $ul
        <script>
        function see(type,targetCla,targetFun,targetId,messageId){
            $.post(root+'control/adIndex.html?cla=homepage&fun=see',{messageId:messageId},function(res) {
               if (res.warn ===2){
                    newIframe(type+'详情',root+'control/adIndex.html?cla='+targetCla+'&fun='+targetFun+'&id='+targetId)
               }else{
                   warn(res.warn);
               }
            },'json')
        }
</script>
EOT;
	}
	
	
	/**
	 * 更新消息状态
	 *
	 * @return string
	 */
	public function see(): string
	{
		$id   = $this->post('messageId');
		$warn = update(array('table' => 'message', 'field' => ['see' => '是', 'seeTime' => $this->time], 'where' => " id = $id"));
		if ($warn == '更新成功') {
			$json['warn'] = 2;
		} else {
			$json['warn'] = '查看失败';
		}
		return json_encode($json, 320);
	}
	
	/**
	 * 数据看板
	 *
	 * @param array $data 格式 [ 'title'=>'标题', 'fun'=>'数据源函数', 'condition'=> '显示查询条件，为空表示显示' , 'query_item'=> '自定义查询条件' ]
	 */
	public static function dataBoard(array $data): string
	{
		$endMoon   = date("Y-m");
		$startMoon = date("Y-m", strtotime('-1 month'));
		if (isset($data['startDate'])) {
			$startMoon = $data['startDate'];
		}
		if (isset($data['endDate'])) {
			$endMoon = $data['endDate'];
		}
		$html        = '';
		$isCondition = (!isset($data['condition']) || $data['condition'] !== false);
		if ($isCondition) {
			if (!isset($data['query_item'])) {
				$dateText = text(["name" => "months", "title" => "时间段", "class" => "text text-data right contour width200", "value" => $startMoon . ' ~ ' . $endMoon, 'laydate' => ['range' => '~', 'type' => 'month']]);
			} elseif ($data['query_item'] == 'client') {
				$dateText = text([
						'name'    => 'months',
						'title'   => "时间段",
						"class"   => "text text-data right contour width200",
						"value"   => date('Y-m', strtotime('-11 month')) . ' ~ ' . date('Y-m'),
						'laydate' => ['range' => '~', 'type' => 'month',],
					]) . selectMultiple(["name" => "staffId", 'table' => " staff", 'class' => " text right contour width200", 'sqlId' => 'stid', 'sqlField' => 'name', 'where' => " state <> '离职' ", 'title' => '员工']);
			}
			$html .= <<<EOT
			<form name='{$data['fun']}Form' onsubmit="return searchFormSub('homepage', '{$data['fun']}')">
			    <p>
				<span class="title-card">{$data['title']}</span>
				<span class="search-ico right" onclick="return searchFormSub('homepage', '{$data['fun']}')"></span>
				$dateText
				</p>
			</form>
EOT;
		}
		$isCondition = settype($isCondition, "int");
		$html        .= <<<EOT
<div id='{$data['fun']}Html' class='data-box-show'>数据查询中。。。</div>
EOT;
		if (!in_array($data['title'], ['回款率', '现金占比', '客户来源'])) {
			$html .= <<<eof
            <script>
            $(function(){searchForm('homepage', '{$data['fun']}', 1)})
            </script>
eof;
		}
		//返回
		return $html;
	}
	
	/**
	 * 离职趋势 数据
	 *
	 * @return string
	 */
	public function turnoverRate(): string
	{
		$date         = $this->post('date');
		$departmentId = $this->post('departmentId');
		if (!empty($date)) {
			$timeArr = explode(' ~ ', $date);
		} else {
			$timeArr[0] = date('Y-m') . '-01';
			$timeArr[1] = $this->date;
		}
		$dateArr = self::getDatesBetweenTwoDays($timeArr[0], $timeArr[1]);
		$res     = [];
		$and     = '';
		$and2    = '';
		if ($departmentId) {
			$departments = self::getDepartmentSub(["where" => " pid = '$departmentId' "]);
			$departments = array_merge([$departmentId], explode(',', trim($departments)));
			$and         .= "  and jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ";
			$and2        .= "  and st.jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ";
		}
		foreach ($dateArr as $date) {
			$quitNum      = find([
				'table'  => "staff_quit_record",
				'field'  => "IFNULL(count(id),0) as num",
				'single' => " state = '已通过' and confirmDate = '$date' " . $and,
			])['num'] ?? 0;
			$entryNum     = find([
				'table'  => "staff_entry_record",
				'field'  => "IFNULL(count(id),0) as num",
				'single' => " state = '已通过' and entryDate = '$date' " . $and,
			])['num'] ?? 0;
			$onJobNum     = find([
				'table'  => "staff as st left join staff_entry_record as ent on st.talentId = ent.talentId",
				'field'  => "IFNULL(count(st.stid),0) as num",
				'single' => " 1=1  and (
            (date_format(ent.entryDate, '%Y-%m-%d') < '" . $date . "' and (date_format(st.quitDay, '%Y-%m-%d') >= '" . $date . "' or st.quitDay is null)) or (ent.talentId is null and (st.quitDay is null or date_format(st.quitDay, '%Y-%m-%d') >= '" . $date . "'))
            ) " . $and2,
			])['num'] ?? 0;
			$onJobTotal   = $entryNum + $onJobNum;
			$turnoverRate = $onJobTotal == 0 ? 0 : round($quitNum / $onJobTotal * 100, 2);
			$res[]        = [
				'date'         => $date,
				'turnoverRate' => $turnoverRate,
			];
		}
		$data         = [
			"name"   => array_column($res, 'date'),
			"series" => [
				[
					'name' => '离职率',
					'data' => array_column($res, 'turnoverRate'),
				],
			],
		];
		$json['html'] = $this->curve($data);
		return json_encode($json, 320);
	}
	
	
	/**
	 * @param array $data
	 * @return string
	 */
	public static function getDepartmentSub($data = [])
	{
		// 条件
		$data['where'] = $data['where'] ?? "pid='0'";
		// 结果
		$result = find(['table' => 'department', 'where' => $data['where'] . " order by list asc"]);
		$temp   = "";
		if ($result['array']) {
			foreach ($result['array'] as $value) {
				// 判断下级是否存在
				$data['where'] = " pid='{$value['id']}' ";
				$has           = query('department', $data['where']);
				if ($has['id']) {
					$temp .= $value['id'] . ",";
					$temp .= self::getDepartmentSub($data);
				} else {
					$temp .= $value['id'] . ",";
				}
			}
		}
		return $temp;
	}
	
	/**
	 * 入职、离职人员部门分布 - 返回数据
	 */
	public function depDistribute(): bool|string
	{
		$date = $this->post('date');
		if (!empty($date)) {
			$timeArr = explode(' ~ ', $date);
		} else {
			$timeArr[0] = date('Y-m') . '-01';
			$timeArr[1] = $this->date;
		}
		$department = $this->post('departmentId');
		if (empty($department)) {
			$arr = find([
				'table' => "department",
				'field' => "id,name",
				'where' => " pid = '0' ",
			]);
		} else {
			$arr = find([
				'table' => "department",
				'field' => "id,name",
				'where' => " pid = '$department' ",
			]);
			if (static::isNull($arr['array'])) {
				$query          = query("department", " id = '$department' ", 'id,name');
				$arr['array'][] = $query;
			}
		}
		$res = [];
		foreach ((array)$arr['array'] as $array) {
			$departments = self::getDepartmentSub(["where" => " pid = '$array[id]' "]);
			$departments = array_merge([$array['id']], explode(',', trim($departments)));
			$res[]       = [
				'department' => $array['name'],
				'entryNum'   => find([
						'table'  => "staff_entry_record",
						'field'  => "IFNULL(count(id),0) as num",
						'single' => " state = '已通过' and entryDate between '$timeArr[0]' and '$timeArr[1]' and jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ",
					])['num'] ?? 0,
				'quitNum'    => find([
						'table'  => "staff_quit_record",
						'field'  => "IFNULL(count(id),0) as num",
						'single' => " state = '已通过' and confirmDate between '$timeArr[0]' and '$timeArr[1]' and jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ",
					])['num'] ?? 0,
			];
		}
		$data         = [
			"name"   => array_column($res, 'department'),
			"series" => [
				[
					'name' => '入职',
					'data' => array_column($res, 'entryNum'),
				],
				[
					'name' => '离职',
					'data' => array_column($res, 'quitNum'),
				],
			],
		];
		$json['html'] = $this->barCharts($data);
		return json_encode($json, 320);
	}
	
	/**
	 * 入职、离职趋势 数据
	 *
	 * @return string
	 */
	public function entryQuitTrend(): string
	{
		$date         = $this->post('date');
		$departmentId = $this->post('departmentId');
		if (!empty($date)) {
			$timeArr = explode(' ~ ', $date);
		} else {
			$timeArr[0] = date('Y-m') . '-01';
			$timeArr[1] = $this->date;
		}
		$dateArr = self::getDatesBetweenTwoDays($timeArr[0], $timeArr[1]);
		$res     = [];
		$and     = '';
		if ($departmentId) {
			$departments = self::getDepartmentSub(["where" => " pid = '$departmentId' "]);
			$departments = array_merge([$departmentId], explode(',', trim($departments)));
			$and         .= "  and jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ";
		}
		foreach ($dateArr as $date) {
			$res[] = [
				'date'     => $date,
				'entryNum' => find([
						'table'  => "staff_entry_record",
						'field'  => "IFNULL(count(id),0) as num",
						'single' => " state = '已通过' and entryDate = '$date' " . $and,
					])['num'] ?? 0,
				'quitNum'  => find([
						'table'  => "staff_quit_record",
						'field'  => "IFNULL(count(id),0) as num",
						'single' => " state = '已通过' and confirmDate = '$date' " . $and,
					])['num'] ?? 0,
			];
		}
		
		$data         = [
			"name"   => array_column($res, 'date'),
			"series" => [
				[
					'name' => '入职',
					'data' => array_column($res, 'entryNum'),
				],
				[
					'name' => '离职',
					'data' => array_column($res, 'quitNum'),
				],
			],
		];
		$json['html'] = $this->curve($data, 'area');
		return json_encode($json, 320);
	}
	
	/**
	 * 获取两个时间之间的日期
	 *
	 * @param $startDate
	 * @param $endDate
	 * @return array
	 */
	public static function getDatesBetweenTwoDays($startDate, $endDate)
	
	{
		$dates = [];
		if (strtotime($startDate) > strtotime($endDate)) {
			$temp      = $startDate;
			$startDate = $endDate;
			$endDate   = $temp;
		}
		
		if ($startDate == $endDate) {
			// 开始日期与结束日期是同一天时
			array_push($dates, $startDate);
			return $dates;
		} else {
			array_push($dates, $startDate);
			$currentDate = $startDate;
			do {
				$nextDate = date('Y-m-d', strtotime($currentDate . ' +1 days'));
				array_push($dates, $nextDate);
				$currentDate = $nextDate;
			} while ($endDate != $currentDate);
			return $dates;
		}
	}
	
	/**
	 * 总营收
	 *
	 * @return string
	 */
	public function hrData(): string
	{
		//总营收 = 销售收入
		$date         = $this->post('date') ?: date('Y-m') . '-01 ~ ' . date('Y-m-d');
		$departmentId = $this->post('departmentId');
		$and          = "";
		$entryAnd     = "";
		$quitAnd      = "";
		if ($date) {
			$entryAnd .= $this->timeComparison($date, 'date', 'entryDate');
			$quitAnd  .= $this->timeComparison($date, 'date', 'quitDate');
		}
		if ($departmentId) {
			$departments = self::getDepartmentSub(["where" => " pid = '$departmentId' "]);
			$departments = array_merge([$departmentId], explode(',', trim($departments)));
			$entryAnd    .= "  and jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ";
			$quitAnd     .= "  and jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ";
			$and         .= "  and st.jobId in (select id from job where departmentId in ('" . implode("','", $departments) . "')) ";
		}
		$entryNum = find([
			'table'  => "staff_entry_record",
			'field'  => "IFNULL(count(id),0) as num",
			'single' => " state = '已通过' " . $entryAnd,
		])['num'] ?? 0;
		$quitNum  = find([
			'table'  => "staff_quit_record",
			'field'  => "IFNULL(count(id),0) as num",
			'single' => " state = '已通过' " . $quitAnd,
		])['num'] ?? 0;
		$data     = explode('~', $date);
		if (is_array($data)) {
			$startStamp = strtotime(trim($data[0]));
			$endStamp   = strtotime(trim(end($data)));
			//查询条件说明，期初在职人数，1、入职时间小于筛选时间段的开始时间，并且离职时间大于等于筛选时间段的开始或者未离职，2、没有入职记录，并且未离职或离职时间大于等于筛选时间段的开始
			$and .= " and (
            (date_format(ent.entryDate, '%Y-%m-%d') < '" . date('Y-m-d', $startStamp) . "' and (date_format(st.quitDay, '%Y-%m-%d') >= '" . date('Y-m-d', $startStamp) . "' or st.quitDay is null)) or (ent.talentId is null and (st.quitDay is null or date_format(st.quitDay, '%Y-%m-%d') >= '" . date('Y-m-d', $startStamp) . "'))
            ) ";
		}
		$onJobNum     = find([
			'table'  => "staff as st left join staff_entry_record as ent on st.talentId = ent.talentId",
			'field'  => "IFNULL(count(st.stid),0) as num",
			'single' => " 1=1 " . $and,
		])['num'] ?? 0;
		$inJobNum     = $onJobNum + $entryNum;
		$turnoverRate = $inJobNum == 0 ? 0 : round($quitNum / $inJobNum * 100, 2);
		$json['html'] = <<<EOT
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">入职人数</p>
                <p class="hr-p f-30">$entryNum</p>
            </div>
        </li>
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">离职人数</p>
                <p class="hr-p f-30">$quitNum</p>
            </div>
        </li>
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">在职人数</p>
                <p class="hr-p f-30">$onJobNum</p>
            </div>
        </li>
        <li class="quarter left vertical-line-hr">
            <div class="hr-div">
                <p class="hr-p gray f-14">离职率</p>
                <p class="hr-p f-30">$turnoverRate%</p>
            </div>
        </li>
EOT;
		return json_encode($json, 320);
	}
	
	/**
	 * 销售成本
	 */
	public static function costOfSales($num): float
	{
		$totalMoney = find([
			'table'  => "machining_in_order as a join machining_in_order_detail as b on a.id = b.orderId",
			'field'  => "(b.fee+b.energyFee+((select ifnull(sum(num),0) from inventory_detail where sourceId = b.id)*b.price)) as money",
			'single' => " a.state = '已确认' ",
		])['money'] ?? 0;
		$totalNum   = find([
			'table'  => "machining_in_order as a join machining_in_order_detail as b on a.id = b.orderId",
			'field'  => "(select ifnull(sum(num),0) from inventory_detail where sourceId = b.id) as num",
			'single' => " a.state = '已确认' ",
		])['num'] ?? 0;
		return $totalNum > 0 ? ($totalMoney / $totalNum * $num) : 0;
	}
	
	/**
	 * 总营收
	 *
	 * @return string
	 */
	public function totalRevenue(): string
	{
		//总营收 = 销售收入
		$month = $this->post('months');
		#[ArrayShape(['income' => "mixed", 'cost' => "float|int", 'margin' => "mixed"])] function calc($obj, $month = null): array
		{
			//全等查询数组
			$equal = [
				"b.state" => '已确认',
			];
			$and   = "";
			if ($month) {
				$and .= $obj->timeComparison($month, 'month', 'b.recordDate');
			}
			//获取查询结果
			$where       = search(["=" => $equal]) . $and;
			$page        = find([
				"table" => "sale_order_detail as a join sale_order as b on a.orderId = b.id join material as c on c.id = a.materialId",
				'field' => "a.*,b.orderNo,b.recordDate,b.contractId,b.khid,c.code,c.name as materialName,c.model,c.unit,b.deliveryDate,b.manager,b.type", "where" => $where,
				"order" => "a.list desc,a.time desc",
			]);
			$incomeTotal = $costTotal = $marginTotal = 0;
			//获取记录
			foreach ($page['array'] as $array) {
				//发货出库数量
				$outNum = find([
					'table' => 'inventory_detail',
					'where' => "sourceId in (select id from sale_send_order_detail where saleOrderMxId = '$array[id]')",
					'sum'   => "num",
				]);
				//退货入库数量
				$inNum = find([
					'table' => 'inventory_detail',
					'where' => "sourceId in (select id from sale_refund_order_detail where sourceId = '$array[id]')",
					'sum'   => "num",
				]);
				//出库金额
				$outMoney = find([
					'table' => 'inventory_detail',
					'where' => "sourceId in (select id from sale_send_order_detail where saleOrderMxId = '$array[id]')",
					'sum'   => "money",
				]);
				//退货金额
				$refundMoney = find([
					'table' => 'inventory_detail',
					'where' => "sourceId in (select id from sale_refund_order_detail where sourceId = '$array[id]')",
					'sum'   => "money",
				]);
				$income      = $outMoney - $refundMoney;
				$cost        = saleProfitClass::cost($array['id'], $outNum - $inNum, false);
				$incomeTotal += $income;
				$costTotal   += $cost;
				$marginTotal += ($income - $cost);
			}
			return [
				'income' => $incomeTotal,
				'cost'   => $costTotal,
				'margin' => $marginTotal,
			];
		}
		
		$result = calc($this, $month);
		return <<<EOT
        <p>总营收</p>
        <hr class="pad10 mag10">
        <hr class="pad10 mag10">
        <h3 id="totalRevenue"><b>￥{$this->formateNumber($result['income'], "万")}</b></h3>
        <hr class="pad10 mag10">
        <p class="gray" id="cost-profit">成本 {$this->formateNumber($result['cost'], "万")}，毛利{$this->formateNumber($result['margin'], "万")}</p>
EOT;
	}
	
	/**
	 * 回款率 - 返回数据
	 *
	 * @return string
	 */
	public function receivableData(): string
	{
		$where = " a.type = '客户' ";
		$month = $this->post('months');
		if (!static::isNull($month)) {
			$where .= self::timeComparison($month, 'month', 'targetDate');
		}
		//销售金额
		$saleMoney = find([
			"table" => "record as a join kehu as b on a.typeId = b.khid",
			'sum'   => "money",
			"where" => $where . " AND a.classify not in  ('收款单核销', '核销') ",
		]);
		//实际收款金额
		$recMoney = find([
			"table" => "record as a join kehu as b on a.typeId = b.khid",
			'sum'   => "money",
			"where" => $where . " AND a.classify in  ('收款单核销', '核销') ",
		]);
		// 回款率=已回款/应回款
		$ratio        = $saleMoney > 0 ? round(($recMoney / $saleMoney) * 100, 2) : 0;
		$unit         = static::$unit;
		$html         = <<<EOT
        <div class="right receivableData gray">
            <p>应回款 $unit {$this->formateNumber($saleMoney, "万")}</p>
            <p>已回款 $unit {$this->formateNumber($recMoney != 0 ? (-1 * $recMoney) : 0, "万")} </p>
            <p>回款率 $ratio %</p>
        </div>
EOT;
		$data         = [
			"series" => [
				[
					'name' => '回款率',
					'data' => $ratio / 100, //不能大于1
				],
			],
		];
		$json['html'] = $this->liquidfill($data) . $html;
		return json_encode($json, 320);
	}
	
	/**
	 * 现金占比 - 返回数据
	 *
	 * @return string
	 */
	public function cashRatioData(): string
	{
		function calc($obj, $type, $month = null)
		{
			$where = " r.state = '已确认' ";
			if (!$obj::isNull($month)) {
				$where .= $obj->timeComparison($month, 'month', 'recordDate');
			}
			return find([
				"table" => "receipt_detail as d join receipt as r on d.orderId = r.id",
				'sum'   => "money",
				"where" => $where . " AND d.settleType = '$type' and r.classify=1",
			]);
		}
		
		// 日期条件
		$month        = $this->post('months');
		$cash         = calc($this, '现金', $month);
		$bill         = calc($this, '票据', $month);
		$sum          = $cash + $bill;
		$cashRate     = ($sum > 0) ? $cash / $sum : 0;
		$billRate     = ($sum > 0) ? $bill / $sum : 0;
		$html         = '
        <div class="gray cash-ratio-span">现金 ' . $this->formateNumber($cash, '万') . '，票据 ' . $this->formateNumber($bill, '万') . '</div>';
		$data         = [
			"series" => [
				[
					'name' => '现金',
					'data' => $cashRate, //不能大于1
				],
				[
					'name' => '票据',
					'data' => $billRate,
				],
			],
		];
		$json['html'] = $this->contrast($data) . $html;
		return json_encode($json, 320);
	}
	
	/**
	 * 客户来源 - 返回数据
	 *
	 * @return string
	 */
	public function clientSourceData(): string
	{
		return (new customerAnalysisClass())->clientSourceData($this->post('months'));
	}
	
	/**
	 * 销售漏斗 - 返回数据
	 *
	 * @return string
	 */
	public function cluesData(): string
	{
		$where = '';
		$month = $this->post('months');
		if (!static::isNull($month)) {
			$where .= self::timeComparison($month, 'month');
		}
		$tableArray = ['线索', '潜在客户', '目标客户', '商机', '成交'];
		$result     = [];
		foreach ($tableArray as $type) {
			$total    = match ($type) {
				'线索'     => static::total([
					'table' => 'clue',
					'where' => $where,
				]),
				'潜在客户' => static::total([
					'table' => 'kehu',
					'where' => " `workFlow` in ('初次联系', '跟进客户')" . $where,
				]),
				'目标客户' => static::total([
					'table' => 'kehu',
					'where' => " `workFlow` ='意向客户' " . $where,
				]),
				'商机'     => static::total([
					'table' => 'opportunity',
					'where' => " `stage` = '已签单' " . $where,
				]),
				'成交'     => static::total([
					'table' => 'sales_contract',
					'where' => " `state` ='已通过' " . $where,
				]),
			};
			$result[] = [
				'name' => $type,
				'data' => $total,
			];
		}
		$data['series'] = $result;
		$json['html']   = $this->funnel($data);
		return json_encode($json, 320);
	}
	
	/**
	 * 行业与规模客户数 - 返回数据
	 *
	 * @return string
	 */
	public function industryScale(): string
	{
		return (new customerAnalysisClass())->industryScale($this->post('months'));
	}
	
	/**
	 * 项目进度 - 返回数据
	 *
	 * @return string
	 */
	public function progressData(): string
	{
		$data         = [
			"series" => [
				[
					'name' => '调研需求',
					'data' => ['2021-04-18', '2021-04-19'],
				],
				[
					'name' => '制定方案',
					'data' => ['2021-04-19', '2021-04-22'],
				],
				[
					'name' => '设计原型',
					'data' => ['2021-04-22', '2021-04-25'],
				],
				[
					'name' => '代码编写',
					'data' => ['2021-04-26', '2021-05-25'],
				],
				[
					'name' => '测试交付',
					'data' => ['2021-05-26', '2021-05-30'],
				],
				[
					'name' => '项目上线',
					'data' => ['2021-05-30', '2021-06-02'],
				],
			],
		];
		$json['html'] = $this->gantt($data);
		return json_encode($json, 320);
	}
	
	/**
	 * 工资曲线 - 返回数据
	 */
	public function wagesData(): bool|string
	{
		$month = $this->post('months');
		if (!empty($month)) {
			$timeArr = explode(' ~ ', $month);
		} else {
			$timeArr[0] = $this->date;
			$timeArr[1] = date('Y-m-d', strtotime("-12 month"));
		}
		$dataArr = self::dateRange($timeArr[0], $timeArr[1]);
		$name    = [];
		$xData   = [];
		foreach ($dataArr as $month) {
			$name[]  = $month;
			$result  = query('work_sign_record', "isPay = 1 and stid = '{$this->control['stid']}' and month = '$month'");
			$xData[] = $result['payMoney'];
		}
		$data         = [
			"name"   => $name,
			"series" => [
				[
					'name' => '工资',
					'data' => $xData,
				],
			],
		];
		$json['html'] = $this->barCharts($data);
		return json_encode($json, 320);
	}
	
	
	/**
	 * 订单与回款 数据
	 *
	 * @return string
	 */
	public function orderData(): string
	{
		function calc($obj, $operator, $month)
		{
			$where = $obj->timeComparison($month, 'month', 'targetDate');
			return find([
				"table" => "record",
				'sum'   => "money",
				"where" => "type = '客户' AND classify $operator ('收款单核销', '核销') " . $where,
			]);
		}
		
		$month = $this->post('months');
		if (!empty($month)) {
			$timeArr = explode(' ~ ', $month);
		} else {
			$timeArr[0] = $this->date;
			$timeArr[1] = date('Y-m-d', strtotime("-12 month"));
		}
		$monthArr = self::dateRange($timeArr[0], $timeArr[1]);
		$res      = [];
		foreach ($monthArr as $month) {
			$res[] = [
				'month'     => $month,
				'saleMoney' => calc($this, 'not in', $month),
				'recMoney'  => calc($this, 'in', $month),
			];
		}
		$data         = [
			"name"   => array_column($res, 'month'),
			"series" => [
				[
					'name' => '订单金额',
					'data' => array_column($res, 'saleMoney'),
				],
				[
					'name' => '回款金额',
					'data' => array_column($res, 'recMoney'),
				],
			],
		];
		$json['html'] = $this->curve($data);
		return json_encode($json, 320);
	}
	
	
	/*日志量-页面*/
	public function logs(): string
	{
		//数据准备
		$endDay   = date("Y-m-d");                         //当前日期
		$startDay = date("Y-m-d", time() - 3600 * 24 * 30);//30天之前
		//生成页面
		//返回
		return "
        <li>
            <div>
                <form name='logDataForm' onsubmit=\"return searchFormSub('homepage','logData')\">日志量：" .
		       text(array("name" => "startDay", "laydate" => [], "title" => "日期", "class" => "titleText", "value" => $startDay)) . "\n-\n" .
		       text(array("name" => "endDay", "laydate" => [], "title" => "日期", "class" => "titleText", "value" => $endDay)) . "
                <input type='submit' value='查询' class='titleSub'>
                </form>
            </div>
            <div id='logDataHtml'>数据查询中。。。</div>
        </li>
        <script>$(function(){searchForm('homepage','logData',1)});</script>
        ";
	}
	
	/*日志量-返回数据*/
	public function logData(): bool|string
	{
		//查询最早的日志
		$earliestLog = query("log", "stid = '" . $this->control['stid'] . "' order by time ");
		//判断
		if (empty($this->post('startDay'))) {
			$json['html'] = "请填写开始日期";
		} elseif (empty($this->post('endDay'))) {
			$json['html'] = "请填写结束日期";
		} elseif (strtotime(date("Y-m-d", strtotime($earliestLog['time']))) > strtotime($this->post('startDay'))) {
			$json['html'] = $earliestLog['time'] . "前未查到你的任何日志记录";
		} elseif (strtotime($this->post('startDay')) > strtotime($this->post('endDay'))) {
			$json['html'] = "开始日期不能大于结束日期";
		} elseif (strtotime($this->post('endDay') . " 00:00:00") > time()) {
			$json['html'] = "结束日期不得大于当前日期";
		} else {
			//分析数据
			$list  = $log = [];
			$today = strtotime($this->post('startDay'));
			while ($today < strtotime($this->post('endDay'))) {
				$today     += 3600 * 24;
				$timeStart = date("Y-m-d", $today) . " 00:00:00";
				$timeEnd   = date("Y-m-d", $today) . " 23:59:59";
				$list[]    = date("Y-m-d", $today);
				$logSql    = find(array(
					"table" => "log",
					"where" => " stid = '" . $this->control['stid'] . "' and time >= '$timeStart' and time <= '$timeEnd'",
				));
				$log[]     = $logSql['num'];
			}
			//生成json
			if (empty($json['html'])) {
				$json['html'] = $this->curve(array(
					"name"   => $list,
					"series" => array(
						array(
							"name" => "当天日志量",
							"data" => $log,
						),
					),
				));
			}
		}
		//返回
		return json_encode($json, 320);
	}
	
	/**
	 * 修改coid
	 */
	public function updateCoid(): bool|string
	{
		$coid = $this->post('coid');
		if (empty($coid)) {
			$json['warn'] = '未找到此账套';
		} else {
			$company = query('company', "coid = '$coid'");
			if (empty($company['coid'])) {
				$json['warn'] = '未找到此账套';
			} elseif ($company['coid'] == self::$coid) {
				$json['warn'] = '当前正在使用，无需更换';
			} else {
				$bool = self::updateCoidRecord($coid);
				if ($bool) {
					self::$coid = $coid;
					$this->insertDefault();
					$json['warn'] = 2;
				} else {
					$json['warn'] = '切换失败';
				}
			}
		}
		return json_encode($json, 320);
	}
	
	/**
	 * 切换菜单
	 */
	public function setMenu(): bool|string
	{
		$field['menu'] = $this->post('menu');
		if (!$field['menu']) {
			$json['warn'] = '参数错误';
		} else {
			$json['warn'] = static::update([
				'table' => 'user',
				'field' => $field,
				'where' => " uid = '" . self::$user['uid'] . "'",
			]);
			if (in_array($json['warn'], ["新增成功", "更新成功"])) {
				$json['warn'] = 2;
			}
		}
		return json_encode($json, 320);
	}
	
	/**
	 * 获取二级菜单
	 */
	public function getMenuTwo(): bool|string
	{
		$menu = $this->post('menu');
		if (!$menu) {
			$data['warn'] = '参数错误';
		} else {
			$data = [
				'warn' => 2,
				'html' => $this->getframeLeft($menu),
			];
		}
		return json_encode($data, 320);
	}
	
	/**
	 * 获取临时内容
	 *
	 * @return string
	 */
	function getTemp(): string
	{
		$cla  = $this->post('cla');
		$fun  = $this->post('fun');
		$resp = [];
		if (empty($cla) || empty($fun)) {
			$resp['warn'] = '参数错误';
		} else {
			$where        = generateWhere([
				'cla'  => $cla,
				'fun'  => $fun,
				'stid' => self::$stid,
			]);
			$info         = query('content_temp', $where);
			$resp['warn'] = 2;
			$data         = [];
			if (!empty($info['text'])) {
				$temp  = static::htmlDecode($info['text']);
				$forms = json_decode($temp, true);
				parse_str($forms, $data);
			}
			$resp['data'] = $data;
			
		}
		
		return json_encode($resp, 320);
	}
	
	/**
	 * 删除草稿内容
	 *
	 * @return void
	 */
	function delTemp(): void
	{
		$str    = $this->post('str');
		$string = parse_url($str, PHP_URL_QUERY);
		parse_str(static::htmlDecode($string), $data);
		$where = [
			'cla'  => $data['cla'],
			'fun'  => substr($data['fun'], 0, strlen($data['fun']) - 4),
			'stid' => self::$stid,
		];
		delete(['table' => 'content_temp', 'where' => generateWhere($where)]);
	}
	
	/**
	 * 保存临时内容
	 *
	 * @return string
	 */
	public function saveTemp(): string
	{
		$field      = [
			'cla'  => $this->post('cla'),
			'fun'  => $this->post('fun'),
			'text' => $this->post('body'),
			'stid' => static::$stid,
		];
		$annotation = [
			'cla'  => '页面',
			'fun'  => '页面',
			'text' => '保存内容',
		];
		$rules      = [
			'cla'  => 'required',
			'fun'  => 'required',
			'text' => 'required',
		];
		// 校验是否符合规则
		$vt     = new \verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$resp['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
		} else {
			$wField = $field;
			unset($wField['text']);
			$where = generateWhere($wField);
			$info  = query('content_temp', $where);
			if ($info['id']) {
				$json['warn'] = static::update([
					'table' => 'content_temp',
					'field' => ['text' => json_encode($field['text'], 320)],
					'where' => $where,
				]);
			} else {
				$field['id']   = static::getId();
				$field['text'] = json_encode($field['text'], 320);
				
				$json['warn'] = static::insert([
					'table' => 'content_temp',
					'field' => $field,
				]);
			}
			if (!in_array($json['warn'], ['更新成功', '新增成功'])) {
				$resp['warn'] = '保存失败，未知错误' . $json['warn'];
				// $resp['warn'] = L('homepage.languageToggle.langErr');
			} else {
				$resp['warn']     = 2;
				$_SESSION['warn'] = '保存成功';
				// $_SESSION['warn'] = L('homepage.languageToggle.langSuss');
			}
		}
		
		resp:
		return json_encode($resp, 320);
	}
	
	/*
	 * 切换语言
	 */
	public function languageToggle(): string
	{
		$lang = $this->post('lang');
		if (!$lang) {
			// 参数错误
			$resp['warn'] = L('homepage.languageToggle.langErr');
		} else {
			$where = [
				'type' => '系统语言',
				'stid' => static::$stid,
			];
			$info  = query('user_setting', generateWhere($where));
			if ($info['id']) {
				$json['warn'] = static::update([
					'table' => 'user_setting',
					'field' => ['value' => $lang],
					'where' => generateWhere($where),
				]);
			} else {
				$json['warn'] = static::insert([
					'table' => 'user_setting',
					'field' => array_merge($where, ['value' => $lang]),
				]);
			}
			if (!in_array($json['warn'], ['更新成功', '新增成功'])) {
				$resp['warn'] = L('homepage.languageToggle.langErr');
			} else {
				$_SESSION['lang'] = $lang;
				$resp['warn']     = 2;
				$_SESSION['warn'] = L('homepage.languageToggle.langSuss');
			}
		}
		return json_encode($resp, 320);
	}
	
	/**
	 * 设置能展示的字段
	 */
	public function setField(): string
	{
		$json['code'] = 0;
		$fields       = $this->post('fields');
		$pageStr      = $this->post('page');
		$page         = explode('-', $pageStr)[0];
		if (!$this->power($page, "see")) {
			$json['warn'] = "你没有{$page}页面的查看权限";
		} elseif (empty($fields) || !is_array($fields)) {
			$json['warn'] = '至少展示一个字段';
		} else {
			$wData = [
				'type' => '自定义显示字段',
				'page' => $pageStr,
				'stid' => self::$stid,
			];
			$info  = query('user_setting', generateWhere($wData));
			// 判断类型
			$data['field'] = $fields;
			if ($info['id']) {
				$widths = json_decode($info['value'], true)['width'];
				foreach ($fields as $field) {
					// 判断请求值是否存在
					if (empty($this->post($field))) {
						// 没有提交时
						$widths[$field] = empty($widths[$field]) ? 0 : $widths[$field];
					} else {
						// 提交时
						$widths[$field] = $this->post($field);
					}
				}
				$data['width'] = $widths;
				// 表格宽度
				$json['warn'] = static::update([
					'table' => 'user_setting',
					'field' => ['value' => json_encode($data, 320)],
					'where' => generateWhere($wData),
				]);
			} else {
				$data['width'] = [];
				$json['warn']  = static::insert([
					'table' => 'user_setting',
					'field' => array_merge($wData, ['value' => json_encode($data, 320)]),
				]);
			}
			if (in_array($json['warn'], ['更新成功', '新增成功'])) {
				$json['code']     = 1;
				$_SESSION['warn'] = '设置成功';
			}
		}
		return json_encode($json, 320);
	}
}
